Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  cryptohi_unittest.cc

  Sprache: C
 

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


#include <string>

#if defined(__LP64__) || defined(_WIN64)
#define NSS_TEST_HAVE_LARGE_VA 1
#if defined(_WIN32)
#include <windows.h>
#else
#include <sys/mman.h>
#endif
#endif

#include "gtest/gtest.h"

#include "nss_scoped_ptrs.h"
#include "cryptohi.h"
#include "keyt.h"
#include "keyhi.h"
#include "secitem.h"
#include "secerr.h"

namespace nss_test {

class SignParamsTestF : public ::testing::Test {
 protected:
  ScopedPLArenaPool arena_;
  ScopedSECKEYPrivateKey privk_;
  ScopedSECKEYPublicKey pubk_;
  ScopedSECKEYPrivateKey ecPrivk_;
  ScopedSECKEYPublicKey ecPubk_;

  void SetUp() {
    arena_.reset(PORT_NewArena(2048));

    SECKEYPublicKey *pubk;
    SECKEYPrivateKey *privk = SECKEY_CreateRSAPrivateKey(1024, &pubk, NULL);
    ASSERT_NE(nullptr, pubk);
    pubk_.reset(pubk);
    ASSERT_NE(nullptr, privk);
    privk_.reset(privk);

    SECKEYECParams ecParams = {siBuffer, NULL, 0};
    SECOidData *oidData;
    oidData = SECOID_FindOIDByTag(SEC_OID_CURVE25519);
    ASSERT_NE(nullptr, oidData);
    ASSERT_NE(nullptr,
              SECITEM_AllocItem(NULL, &ecParams, (2 + oidData->oid.len)))
        << "Couldn't allocate memory for OID.";
    ecParams.data[0] = SEC_ASN1_OBJECT_ID; /* we have to prepend 0x06 */
    ecParams.data[1] = oidData->oid.len;
    memcpy(ecParams.data + 2, oidData->oid.data, oidData->oid.len);
    SECKEYPublicKey *ecPubk;
    SECKEYPrivateKey *ecPrivk =
        SECKEY_CreateECPrivateKey(&ecParams, &ecPubk, NULL);
    SECITEM_FreeItem(&ecParams, PR_FALSE);
    ASSERT_NE(nullptr, ecPubk);
    ecPubk_.reset(ecPubk);
    ASSERT_NE(nullptr, ecPrivk);
    ecPrivk_.reset(ecPrivk);
  }

  void CreatePssParams(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) {
    PORT_Memset(params, 0sizeof(SECKEYRSAPSSParams));

    params->hashAlg = (SECAlgorithmID *)PORT_ArenaZAlloc(
        arena_.get(), sizeof(SECAlgorithmID));
    ASSERT_NE(nullptr, params->hashAlg);
    SECStatus rv =
        SECOID_SetAlgorithmID(arena_.get(), params->hashAlg, hashAlgTag, NULL);
    ASSERT_EQ(SECSuccess, rv);
  }

  void CreatePssParams(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag,
                       SECOidTag maskHashAlgTag) {
    CreatePssParams(params, hashAlgTag);

    SECAlgorithmID maskHashAlg;
    PORT_Memset(&maskHashAlg, 0sizeof(maskHashAlg));
    SECStatus rv =
        SECOID_SetAlgorithmID(arena_.get(), &maskHashAlg, maskHashAlgTag, NULL);
    ASSERT_EQ(SECSuccess, rv);

    SECItem *maskHashAlgItem =
        SEC_ASN1EncodeItem(arena_.get(), NULL, &maskHashAlg,
                           SEC_ASN1_GET(SECOID_AlgorithmIDTemplate));

    params->maskAlg = (SECAlgorithmID *)PORT_ArenaZAlloc(
        arena_.get(), sizeof(SECAlgorithmID));
    ASSERT_NE(nullptr, params->maskAlg);

    rv = SECOID_SetAlgorithmID(arena_.get(), params->maskAlg,
                               SEC_OID_PKCS1_MGF1, maskHashAlgItem);
    ASSERT_EQ(SECSuccess, rv);
  }

  void CreatePssParams(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag,
                       SECOidTag maskHashAlgTag, unsigned long saltLength) {
    CreatePssParams(params, hashAlgTag, maskHashAlgTag);

    SECItem *saltLengthItem =
        SEC_ASN1EncodeInteger(arena_.get(), ¶ms->saltLength, saltLength);
    ASSERT_EQ(¶ms->saltLength, saltLengthItem);
  }

  void CheckHashAlg(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) {
    // If hash algorithm is SHA-1, it must be omitted in the parameters
    if (hashAlgTag == SEC_OID_SHA1) {
      EXPECT_EQ(nullptr, params->hashAlg);
    } else {
      EXPECT_NE(nullptr, params->hashAlg);
      EXPECT_EQ(hashAlgTag, SECOID_GetAlgorithmTag(params->hashAlg));
    }
  }

  void CheckMaskAlg(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) {
    SECStatus rv;

    // If hash algorithm is SHA-1, it must be omitted in the parameters
    if (hashAlgTag == SEC_OID_SHA1)
      EXPECT_EQ(nullptr, params->hashAlg);
    else {
      EXPECT_NE(nullptr, params->maskAlg);
      EXPECT_EQ(SEC_OID_PKCS1_MGF1, SECOID_GetAlgorithmTag(params->maskAlg));

      SECAlgorithmID hashAlg;
      rv = SEC_QuickDERDecodeItem(arena_.get(), &hashAlg,
                                  SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
                                  ¶ms->maskAlg->parameters);
      ASSERT_EQ(SECSuccess, rv);

      EXPECT_EQ(hashAlgTag, SECOID_GetAlgorithmTag(&hashAlg));
    }
  }

  void CheckSaltLength(SECKEYRSAPSSParams *params, SECOidTag hashAlg) {
    // If the salt length parameter is missing, that means it is 20 (default)
    if (!params->saltLength.data) {
      return;
    }

    unsigned long value;
    SECStatus rv = SEC_ASN1DecodeInteger(¶ms->saltLength, &value);
    ASSERT_EQ(SECSuccess, rv);

    // The salt length are usually the same as the hash length,
    // except for the case where the hash length exceeds the limit
    // set by the key length
    switch (hashAlg) {
      case SEC_OID_SHA1:
        EXPECT_EQ(20UL, value);
        break;
      case SEC_OID_SHA224:
        EXPECT_EQ(28UL, value);
        break;
      case SEC_OID_SHA256:
        EXPECT_EQ(32UL, value);
        break;
      case SEC_OID_SHA384:
        EXPECT_EQ(48UL, value);
        break;
      case SEC_OID_SHA512:
        // Truncated from 64, because our private key is 1024-bit
        EXPECT_EQ(62UL, value);
        break;
      default:
        FAIL();
    }
  }
};

class SignParamsTest
    : public SignParamsTestF,
      public ::testing::WithParamInterface<std::tuple<SECOidTag, SECOidTag>> {};

class SignParamsSourceTest : public SignParamsTestF,
                             public ::testing::WithParamInterface<SECOidTag> {};

TEST_P(SignParamsTest, CreateRsa) {
  SECOidTag hashAlg = std::get<0>(GetParam());
  SECOidTag srcHashAlg = std::get<1>(GetParam());

  SECItem *srcParams;
  if (srcHashAlg != SEC_OID_UNKNOWN) {
    SECKEYRSAPSSParams pssParams;
    ASSERT_NO_FATAL_FAILURE(
        CreatePssParams(&pssParams, srcHashAlg, srcHashAlg));
    srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
                                   SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
    ASSERT_NE(nullptr, srcParams);
  } else {
    srcParams = NULL;
  }

  SECItem *params = SEC_CreateSignatureAlgorithmParameters(
      arena_.get(), nullptr, SEC_OID_PKCS1_RSA_ENCRYPTION, hashAlg, srcParams,
      privk_.get());

  // PKCS#1 RSA actually doesn't take any parameters, but if it is
  // given, return a copy of it
  if (srcHashAlg != SEC_OID_UNKNOWN) {
    EXPECT_EQ(srcParams->len, params->len);
    EXPECT_EQ(0, memcmp(params->data, srcParams->data, srcParams->len));
  } else {
    EXPECT_EQ(nullptr, params);
  }
}

TEST_P(SignParamsTest, CreateRsaPss) {
  SECOidTag hashAlg = std::get<0>(GetParam());
  SECOidTag srcHashAlg = std::get<1>(GetParam());

  SECItem *srcParams;
  if (srcHashAlg != SEC_OID_UNKNOWN) {
    SECKEYRSAPSSParams pssParams;
    ASSERT_NO_FATAL_FAILURE(
        CreatePssParams(&pssParams, srcHashAlg, srcHashAlg));
    srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
                                   SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
    ASSERT_NE(nullptr, srcParams);
  } else {
    srcParams = NULL;
  }

  SECItem *params = SEC_CreateSignatureAlgorithmParameters(
      arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
      srcParams, privk_.get());

  if (hashAlg != SEC_OID_UNKNOWN && srcHashAlg != SEC_OID_UNKNOWN &&
      hashAlg != srcHashAlg) {
    EXPECT_EQ(nullptr, params);
    return;
  }

  EXPECT_NE(nullptr, params);

  SECKEYRSAPSSParams pssParams;
  PORT_Memset(&pssParams, 0sizeof(pssParams));
  SECStatus rv =
      SEC_QuickDERDecodeItem(arena_.get(), &pssParams,
                             SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate), params);
  ASSERT_EQ(SECSuccess, rv);

  if (hashAlg == SEC_OID_UNKNOWN) {
    if (!pssParams.hashAlg) {
      hashAlg = SEC_OID_SHA1;
    } else {
      hashAlg = SECOID_GetAlgorithmTag(pssParams.hashAlg);
    }

    if (srcHashAlg == SEC_OID_UNKNOWN) {
      // If both hashAlg and srcHashAlg is unset, NSS will decide the hash
      // algorithm based on the key length; in this case it's SHA256
      EXPECT_EQ(SEC_OID_SHA256, hashAlg);
    } else {
      EXPECT_EQ(srcHashAlg, hashAlg);
    }
  }

  ASSERT_NO_FATAL_FAILURE(CheckHashAlg(&pssParams, hashAlg));
  ASSERT_NO_FATAL_FAILURE(CheckMaskAlg(&pssParams, hashAlg));
  ASSERT_NO_FATAL_FAILURE(CheckSaltLength(&pssParams, hashAlg));

  // The default trailer field (1) must be omitted
  EXPECT_EQ(nullptr, pssParams.trailerField.data);
}

TEST_P(SignParamsTest, CreateRsaPssWithECPrivateKey) {
  SECOidTag hashAlg = std::get<0>(GetParam());
  SECOidTag srcHashAlg = std::get<1>(GetParam());

  SECItem *srcParams;
  if (srcHashAlg != SEC_OID_UNKNOWN) {
    SECKEYRSAPSSParams pssParams;
    ASSERT_NO_FATAL_FAILURE(
        CreatePssParams(&pssParams, srcHashAlg, srcHashAlg));
    srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
                                   SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
    ASSERT_NE(nullptr, srcParams);
  } else {
    srcParams = NULL;
  }

  SECItem *params = SEC_CreateSignatureAlgorithmParameters(
      arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
      srcParams, ecPrivk_.get());

  EXPECT_EQ(nullptr, params);
}

TEST_P(SignParamsTest, CreateRsaPssWithInvalidHashAlg) {
  SECOidTag srcHashAlg = std::get<1>(GetParam());

  SECItem *srcParams;
  if (srcHashAlg != SEC_OID_UNKNOWN) {
    SECKEYRSAPSSParams pssParams;
    ASSERT_NO_FATAL_FAILURE(
        CreatePssParams(&pssParams, srcHashAlg, srcHashAlg));
    srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
                                   SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
    ASSERT_NE(nullptr, srcParams);
  } else {
    srcParams = NULL;
  }

  SECItem *params = SEC_CreateSignatureAlgorithmParameters(
      arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, SEC_OID_MD5,
      srcParams, privk_.get());

  EXPECT_EQ(nullptr, params);
}

TEST_P(SignParamsSourceTest, CreateRsaPssWithInvalidHashAlg) {
  SECOidTag hashAlg = GetParam();

  SECItem *srcParams;
  SECKEYRSAPSSParams pssParams;
  ASSERT_NO_FATAL_FAILURE(
      CreatePssParams(&pssParams, SEC_OID_MD5, SEC_OID_MD5));
  srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
                                 SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
  ASSERT_NE(nullptr, srcParams);

  SECItem *params = SEC_CreateSignatureAlgorithmParameters(
      arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
      srcParams, privk_.get());

  EXPECT_EQ(nullptr, params);
}

TEST_P(SignParamsSourceTest, CreateRsaPssWithInvalidSaltLength) {
  SECOidTag hashAlg = GetParam();

  SECItem *srcParams;
  SECKEYRSAPSSParams pssParams;
  ASSERT_NO_FATAL_FAILURE(
      CreatePssParams(&pssParams, SEC_OID_SHA512, SEC_OID_SHA512, 100));
  srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
                                 SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
  ASSERT_NE(nullptr, srcParams);

  SECItem *params = SEC_CreateSignatureAlgorithmParameters(
      arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
      srcParams, privk_.get());

  EXPECT_EQ(nullptr, params);
}

TEST_P(SignParamsSourceTest, CreateRsaPssWithHashMismatch) {
  SECOidTag hashAlg = GetParam();

  SECItem *srcParams;
  SECKEYRSAPSSParams pssParams;
  ASSERT_NO_FATAL_FAILURE(
      CreatePssParams(&pssParams, SEC_OID_SHA256, SEC_OID_SHA512));
  srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
                                 SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
  ASSERT_NE(nullptr, srcParams);

  SECItem *params = SEC_CreateSignatureAlgorithmParameters(
      arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
      srcParams, privk_.get());

  EXPECT_EQ(nullptr, params);
}

INSTANTIATE_TEST_SUITE_P(
    SignParamsTestCases, SignParamsTest,
    ::testing::Combine(::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1,
                                         SEC_OID_SHA224, SEC_OID_SHA256,
                                         SEC_OID_SHA384, SEC_OID_SHA512),
                       ::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1,
                                         SEC_OID_SHA224, SEC_OID_SHA256,
                                         SEC_OID_SHA384, SEC_OID_SHA512)));

INSTANTIATE_TEST_SUITE_P(SignParamsSourceTestCases, SignParamsSourceTest,
                         ::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1,
                                           SEC_OID_SHA224, SEC_OID_SHA256,
                                           SEC_OID_SHA384, SEC_OID_SHA512));

#ifdef NSS_TEST_HAVE_LARGE_VA
// Bug 2027345: chosen so (dst_len - kOversizedLen) wraps to a positive int32.
static const size_t kOversizedLen = 0x80000021UL;

// Reserve `size` bytes of virtual address space.  Touched pages are committed
// lazily (POSIX) or explicitly via CommitTouchedRange (Windows), so untouched
// regions consume no backing memory.  Returns nullptr on failure.
static unsigned char *ReserveSparseRange(size_t size) {
#if defined(_WIN32)
  return static_cast<unsigned char *>(
      VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_NOACCESS));
#else
  int flags = MAP_PRIVATE | MAP_ANONYMOUS;
#ifdef MAP_NORESERVE
  flags |= MAP_NORESERVE;
#endif
  void *p = mmap(nullptr, size, PROT_READ | PROT_WRITE, flags, -10);
  return p == MAP_FAILED ? nullptr : static_cast<unsigned char *>(p);
#endif
}

// Ensure the pages covering [offset, offset + len) of a region returned by
// ReserveSparseRange are readable and writable.  No-op on POSIX, where
// anonymous mappings are demand-paged automatically.  Returns true on success.
static bool CommitTouchedRange(unsigned char *base, size_t offset, size_t len) {
#if defined(_WIN32)
  SYSTEM_INFO si;
  GetSystemInfo(&si);
  size_t page = si.dwPageSize;
  size_t start = offset & ~(page - 1);
  size_t end = (offset + len + page - 1) & ~(page - 1);
  return VirtualAlloc(base + start, end - start, MEM_COMMIT, PAGE_READWRITE) !=
         nullptr;
#else
  (void)base;
  (void)offset;
  (void)len;
  return true;
#endif
}

static void ReleaseSparseRange(unsigned char *base, size_t size) {
#if defined(_WIN32)
  (void)size;
  VirtualFree(base, 0, MEM_RELEASE);
#else
  munmap(base, size);
#endif
}

// Build a DER SEQUENCE { INTEGER big, INTEGER 01 } (or reversed) in a sparse
// virtual address reservation -- only the touched header bytes and the tail
// small-INTEGER bytes are backed by physical memory; the kOversizedLen-byte
// big-INTEGER content body is never read or written by QuickDER (the parser
// only does pointer arithmetic across it).  Sets *item and *total_out; caller
// must call ReleaseSparseRange on success.  Returns nullptr on failure.
static unsigned char *MakeOversizedDerSig(bool oversized_r, SECItem *item,
                                          size_t *total_out) {
  static const size_t kBigHdr = 6;    // tag(1) + 0x84(1) + 4-byte length
  static const size_t kSmallTlv = 3;  // 02 01 01

  size_t seq_content = kBigHdr + kOversizedLen + kSmallTlv;
  size_t total = 6 + seq_content;  // SEQUENCE header + content
  *total_out = total;

  unsigned char *buf = ReserveSparseRange(total);
  if (buf == nullptr) return nullptr;

  // The leading header region is touched by every test; commit a small chunk
  // covering SEQUENCE + first INTEGER's header and content[0].
  if (!CommitTouchedRange(buf, 064)) {
    ReleaseSparseRange(buf, total);
    return nullptr;
  }

  size_t i = 0;
  buf[i++] = 0x30;  // SEQUENCE
  buf[i++] = 0x84;  // long-form, 4 length bytes follow
  buf[i++] = (seq_content >> 24) & 0xFF;
  buf[i++] = (seq_content >> 16) & 0xFF;
  buf[i++] = (seq_content >> 8) & 0xFF;
  buf[i++] = seq_content & 0xFF;

  auto write_big_at = [&](size_t pos) {
    buf[pos++] = 0x02;  // INTEGER
    buf[pos++] = 0x84;  // long-form, 4 length bytes follow
    buf[pos++] = (kOversizedLen >> 24) & 0xFF;
    buf[pos++] = (kOversizedLen >> 16) & 0xFF;
    buf[pos++] = (kOversizedLen >> 8) & 0xFF;
    buf[pos++] = kOversizedLen & 0xFF;
    // Non-zero so QuickDER's leading-zero strip leaves sig.r.len/sig.s.len
    // at kOversizedLen.  Subsequent content bytes are never read.
    buf[pos] = 0x80;
  };
  auto write_small_at = [&](size_t pos) {
    buf[pos++] = 0x02;
    buf[pos++] = 0x01;
    buf[pos++] = 0x01;
  };

  if (oversized_r) {
    write_big_at(i);
    size_t small_off = i + kBigHdr + kOversizedLen;
    if (!CommitTouchedRange(buf, small_off, kSmallTlv)) {
      ReleaseSparseRange(buf, total);
      return nullptr;
    }
    write_small_at(small_off);
  } else {
    write_small_at(i);
    write_big_at(i + kSmallTlv);
  }

  item->type = siBuffer;
  item->data = buf;
  item->len = static_cast<unsigned int>(total);
  return buf;
}

TEST(DSAUTest, DecodeDerSigOversizedRRejected) {
  SECItem item = {};
  size_t total;
  unsigned char *buf = MakeOversizedDerSig(/*oversized_r=*/true, &item, &total);
  ASSERT_NE(nullptr, buf);
  ScopedSECItem result(DSAU_DecodeDerSig(&item));
  ReleaseSparseRange(buf, total);
  EXPECT_EQ(nullptr, result.get());
}

TEST(DSAUTest, DecodeDerSigOversizedSRejected) {
  SECItem item = {};
  size_t total;
  unsigned char *buf =
      MakeOversizedDerSig(/*oversized_r=*/false, &item, &total);
  ASSERT_NE(nullptr, buf);
  ScopedSECItem result(DSAU_DecodeDerSig(&item));
  ReleaseSparseRange(buf, total);
  EXPECT_EQ(nullptr, result.get());
}

TEST(DSAUTest, VfyVerifyDataDirectOversizedSigRejected) {
  SECKEYECParams ecParams = {siBuffer, nullptr, 0};
  SECOidData *oidData = SECOID_FindOIDByTag(SEC_OID_ANSIX962_EC_PRIME256V1);
  ASSERT_NE(nullptr, oidData);
  ASSERT_NE(nullptr,
            SECITEM_AllocItem(nullptr, &ecParams, 2 + oidData->oid.len));
  ecParams.data[0] = SEC_ASN1_OBJECT_ID;
  ecParams.data[1] = static_cast<unsigned char>(oidData->oid.len);
  memcpy(ecParams.data + 2, oidData->oid.data, oidData->oid.len);

  SECKEYPublicKey *pubk = nullptr;
  ScopedSECKEYPrivateKey privk(
      SECKEY_CreateECPrivateKey(&ecParams, &pubk, nullptr));
  SECITEM_FreeItem(&ecParams, PR_FALSE);
  ScopedSECKEYPublicKey pubKey(pubk);
  ASSERT_NE(nullptr, privk.get());
  ASSERT_NE(nullptr, pubKey.get());

  SECItem sig = {};
  size_t total;
  unsigned char *buf = MakeOversizedDerSig(/*oversized_r=*/true, &sig, &total);
  ASSERT_NE(nullptr, buf);
  const unsigned char data[] = "hello";
  SECStatus rv = VFY_VerifyDataDirect(data, sizeof(data), pubKey.get(), &sig,
                                      SEC_OID_ANSIX962_EC_PUBLIC_KEY,
                                      SEC_OID_SHA256, nullptr, nullptr);
  ReleaseSparseRange(buf, total);
  EXPECT_EQ(SECFailure, rv);
}
#endif  // NSS_TEST_HAVE_LARGE_VA

}  // namespace nss_test

Messung V0.5 in Prozent
C=97 H=97 G=96

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-08-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

letze Version des Elbe Quellennavigators


Jenseits des Üblichen ....

Besucher

Besucher

Statistik
#Sources=277311
#Domains=752002