Commit 78420ecd authored by Franziskus Kiefer's avatar Franziskus Kiefer

Bug 1396830 - add blake2b to freebl, r=mt

Differential Revision: https://nss-review.dev.mozaws.net/D362

--HG--
extra : rebase_source : 9077857559be00c99aaa19684e01c77f9a467740
parent 5eacfc3d
/*
* blake2b_unittest.cc - unittests for blake2b hash function
*
* 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 "blapi.h"
#include "nspr.h"
#include "nss.h"
#include "secerr.h"
#include <cstdlib>
#include <iostream>
#include <memory>
#define GTEST_HAS_RTTI 0
#include "gtest/gtest.h"
#include "kat/blake2b_kat.h"
template <class T>
struct ScopedDelete {
void operator()(T* ptr) {
if (ptr) {
BLAKE2B_DestroyContext(ptr, PR_TRUE);
}
}
};
typedef std::unique_ptr<BLAKE2BContext, ScopedDelete<BLAKE2BContext>>
ScopedBLAKE2BContext;
class Blake2BTests : public ::testing::Test {};
class Blake2BKAT
: public ::testing::TestWithParam<std::pair<int, std::vector<uint8_t>>> {};
class Blake2BKATUnkeyed : public Blake2BKAT {};
class Blake2BKATKeyed : public Blake2BKAT {};
TEST_P(Blake2BKATUnkeyed, Unkeyed) {
std::vector<uint8_t> values(BLAKE2B512_LENGTH);
SECStatus rv =
BLAKE2B_HashBuf(values.data(), kat_data.data(), std::get<0>(GetParam()));
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(values, std::get<1>(GetParam()));
}
TEST_P(Blake2BKATKeyed, Keyed) {
std::vector<uint8_t> values(BLAKE2B512_LENGTH);
SECStatus rv = BLAKE2B_MAC_HashBuf(values.data(), kat_data.data(),
std::get<0>(GetParam()), key.data(),
BLAKE2B_KEY_SIZE);
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(values, std::get<1>(GetParam()));
}
INSTANTIATE_TEST_CASE_P(UnkeyedKAT, Blake2BKATUnkeyed,
::testing::ValuesIn(TestcasesUnkeyed));
INSTANTIATE_TEST_CASE_P(KeyedKAT, Blake2BKATKeyed,
::testing::ValuesIn(TestcasesKeyed));
TEST_F(Blake2BTests, ContextTest) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
SECStatus rv = BLAKE2B_Begin(ctx.get());
ASSERT_EQ(SECSuccess, rv);
size_t src_length = 252;
const size_t quarter = 63;
for (int i = 0; i < 4 && src_length > 0; i++) {
rv = BLAKE2B_Update(ctx.get(), kat_data.data() + i * quarter,
PR_MIN(quarter, src_length));
ASSERT_EQ(SECSuccess, rv);
size_t len = BLAKE2B_FlattenSize(ctx.get());
std::vector<unsigned char> ctxbytes(len);
rv = BLAKE2B_Flatten(ctx.get(), ctxbytes.data());
ASSERT_EQ(SECSuccess, rv);
ScopedBLAKE2BContext ctx_cpy(BLAKE2B_Resurrect(ctxbytes.data(), NULL));
ASSERT_TRUE(ctx_cpy) << "BLAKE2B_Resurrect failed!";
ASSERT_EQ(SECSuccess, PORT_Memcmp(ctx.get(), ctx_cpy.get(), len));
src_length -= quarter;
}
ASSERT_EQ(0U, src_length);
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
rv = BLAKE2B_End(ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH);
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(std::get<1>(TestcasesUnkeyed[252]), digest)
<< "BLAKE2B_End failed!";
}
TEST_F(Blake2BTests, ContextTest2) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
SECStatus rv = BLAKE2B_Begin(ctx.get());
ASSERT_EQ(SECSuccess, rv);
rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128);
ASSERT_EQ(SECSuccess, rv);
rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127);
ASSERT_EQ(SECSuccess, rv);
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
rv = BLAKE2B_End(ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH);
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(std::get<1>(TestcasesUnkeyed[255]), digest)
<< "BLAKE2B_End failed!";
}
TEST_F(Blake2BTests, CloneTest) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ScopedBLAKE2BContext cloned_ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
ASSERT_TRUE(cloned_ctx) << "BLAKE2B_NewContext failed!";
SECStatus rv = BLAKE2B_Begin(ctx.get());
ASSERT_EQ(SECSuccess, rv);
rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 255);
ASSERT_EQ(SECSuccess, rv);
BLAKE2B_Clone(cloned_ctx.get(), ctx.get());
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
rv = BLAKE2B_End(cloned_ctx.get(), digest.data(), nullptr, BLAKE2B512_LENGTH);
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(std::get<1>(TestcasesUnkeyed[255]), digest)
<< "BLAKE2B_End failed!";
}
TEST_F(Blake2BTests, NullTest) {
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
SECStatus rv = BLAKE2B_HashBuf(digest.data(), nullptr, 0);
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(std::get<1>(TestcasesUnkeyed[0]), digest);
digest = std::vector<uint8_t>(BLAKE2B512_LENGTH);
rv = BLAKE2B_MAC_HashBuf(digest.data(), nullptr, 0, key.data(),
BLAKE2B_KEY_SIZE);
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(std::get<1>(TestcasesKeyed[0]), digest);
}
TEST_F(Blake2BTests, HashTest) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
SECStatus rv = BLAKE2B_Hash(digest.data(), "abc");
std::vector<uint8_t> expected = {
0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, 0x6a, 0x27, 0x97,
0xb6, 0x9f, 0x12, 0xf6, 0xe9, 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a,
0xc4, 0xb7, 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, 0xa2, 0xd1, 0x7d,
0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, 0xc2, 0x52, 0xd5, 0xde,
0x45, 0x33, 0xcc, 0x95, 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92,
0x5a, 0xb9, 0x23, 0x86, 0xed, 0xd4, 0x00, 0x99, 0x23};
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(expected, digest);
}
TEST_F(Blake2BTests, LongHashTest) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
SECStatus rv = BLAKE2B_Hash(
digest.data(),
"qwertzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qw"
"ertzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qwer"
"tzuiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789qwertz"
"uiopasdfghjklyxcvbnm123456789qwertzuiopasdfghjklyxcvbnm123456789");
std::vector<uint8_t> expected = {
0x1f, 0x9e, 0xe6, 0x5a, 0xa0, 0x36, 0x05, 0xfc, 0x41, 0x0e, 0x2f,
0x55, 0x96, 0xfd, 0xb5, 0x9d, 0x85, 0x95, 0x5e, 0x24, 0x37, 0xe7,
0x0d, 0xe4, 0xa0, 0x22, 0x4a, 0xe1, 0x59, 0x1f, 0x97, 0x03, 0x57,
0x54, 0xf0, 0xca, 0x92, 0x75, 0x2f, 0x9e, 0x86, 0xeb, 0x82, 0x4f,
0x9c, 0xf4, 0x02, 0x17, 0x7f, 0x76, 0x56, 0x26, 0x46, 0xf4, 0x07,
0xfd, 0x1f, 0x78, 0xdb, 0x7b, 0x0d, 0x24, 0x43, 0xf0};
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(expected, digest);
}
TEST_F(Blake2BTests, TruncatedHashTest) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
SECStatus rv = BLAKE2B_Begin(ctx.get());
ASSERT_EQ(SECSuccess, rv);
rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128);
ASSERT_EQ(SECSuccess, rv);
rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127);
ASSERT_EQ(SECSuccess, rv);
size_t max_digest_len = BLAKE2B512_LENGTH - 5;
std::vector<uint8_t> digest(max_digest_len);
unsigned int digest_len;
rv = BLAKE2B_End(ctx.get(), digest.data(), &digest_len, max_digest_len);
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(digest.size(), digest_len);
ASSERT_EQ(0, memcmp(std::get<1>(TestcasesUnkeyed[255]).data(), digest.data(),
max_digest_len))
<< "BLAKE2B_End failed!";
}
TEST_F(Blake2BTests, TruncatedHashTest2) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
SECStatus rv = BLAKE2B_Begin(ctx.get());
ASSERT_EQ(SECSuccess, rv);
rv = BLAKE2B_Update(ctx.get(), kat_data.data(), 128);
ASSERT_EQ(SECSuccess, rv);
rv = BLAKE2B_Update(ctx.get(), kat_data.data() + 128, 127);
ASSERT_EQ(SECSuccess, rv);
size_t max_digest_len = BLAKE2B512_LENGTH - 60;
std::vector<uint8_t> digest(max_digest_len);
unsigned int digest_len;
rv = BLAKE2B_End(ctx.get(), digest.data(), &digest_len, max_digest_len);
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(digest.size(), digest_len);
}
TEST_F(Blake2BTests, OverlongKeyTest) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
std::vector<uint8_t> key = {
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35};
std::vector<uint8_t> data = {0x61, 0x62, 0x63};
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
SECStatus rv =
BLAKE2B_MAC_HashBuf(digest.data(), data.data(), 3, key.data(), 65);
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
}
TEST_F(Blake2BTests, EmptyKeyTest) {
ScopedBLAKE2BContext ctx(BLAKE2B_NewContext());
ASSERT_TRUE(ctx) << "BLAKE2B_NewContext failed!";
uint8_t key[1]; // A vector.data() would give us a nullptr.
std::vector<uint8_t> data = {0x61, 0x62, 0x63};
std::vector<uint8_t> digest(BLAKE2B512_LENGTH);
SECStatus rv = BLAKE2B_MAC_HashBuf(digest.data(), data.data(), 3, key, 0);
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
if (NSS_NoDB_Init(nullptr) != SECSuccess) {
return 1;
}
int rv = RUN_ALL_TESTS();
if (NSS_Shutdown() != SECSuccess) {
return 1;
}
return rv;
}
......@@ -8,17 +8,10 @@
],
'targets': [
{
'target_name': 'freebl_gtest',
'type': 'executable',
'sources': [
'mpi_unittest.cc',
'dh_unittest.cc',
'ecl_unittest.cc',
'ghash_unittest.cc',
'<(DEPTH)/gtests/common/gtests.cc'
],
# Dependencies for tests.
'target_name': 'freebl_gtest_deps',
'type': 'none',
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/lib/util/util.gyp:nssutil3',
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
......@@ -32,6 +25,21 @@
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
],
},
{
'target_name': 'freebl_gtest',
'type': 'executable',
'sources': [
'mpi_unittest.cc',
'dh_unittest.cc',
'ecl_unittest.cc',
'ghash_unittest.cc',
'<(DEPTH)/gtests/common/gtests.cc'
],
'dependencies': [
'freebl_gtest_deps',
'<(DEPTH)/exports.gyp:nss_exports',
],
},
{
'target_name': 'prng_gtest',
'type': 'executable',
......@@ -39,36 +47,35 @@
'prng_kat_unittest.cc',
],
'dependencies': [
'freebl_gtest_deps',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/lib/util/util.gyp:nssutil3',
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
'<(DEPTH)/lib/base/base.gyp:nssb',
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
'<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix',
],
'conditions': [
[ 'OS=="win"', {
'libraries': [
'advapi32.lib',
],
}],
},
{
'target_name': 'blake2b_gtest',
'type': 'executable',
'sources': [
'blake2b_unittest.cc',
],
'defines': [
'NSS_USE_STATIC_LIBS'
'dependencies': [
'freebl_gtest_deps',
'<(DEPTH)/exports.gyp:nss_exports',
],
},
],
'target_defaults': {
'include_dirs': [
'<(DEPTH)/lib/freebl/ecl',
'<(DEPTH)/lib/freebl/mpi',
'<(DEPTH)/lib/freebl/',
'<(DEPTH)/lib/ssl/',
'<(DEPTH)/lib/util/',
'<(DEPTH)/lib/certdb/',
'<(DEPTH)/lib/cryptohi/',
'<(DEPTH)/lib/pk11wrap/',
],
'defines': [
'NSS_USE_STATIC_LIBS',
],
# For test builds we have to set MPI defines.
'conditions': [
......@@ -85,6 +92,11 @@
'MP_ASSEMBLY_DIV_2DX1D',
],
}],
[ 'OS=="win"', {
'libraries': [
'advapi32.lib',
],
}],
],
},
'variables': {
......
This diff is collapsed.
This diff is collapsed.
/*
* blake2b.h - header file for blake2b hash function
*
* 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/. */
#ifndef BLAKE_H
#define BLAKE_H
#include <stddef.h>
#include <stdint.h>
struct Blake2bContextStr {
uint64_t h[8]; /* chained state */
uint64_t t[2]; /* total number of bytes */
uint64_t f; /* last block flag */
uint8_t buf[BLAKE2B_BLOCK_LENGTH]; /* input buffer */
size_t buflen; /* size of remaining bytes in buf */
size_t outlen; /* digest size */
};
#endif /* BLAKE_H */
......@@ -1400,6 +1400,84 @@ extern SECStatus
TLS_P_hash(HASH_HashType hashAlg, const SECItem *secret, const char *label,
SECItem *seed, SECItem *result, PRBool isFIPS);
/******************************************/
/*
** Implements the Blake2b hash function.
*/
/*
** Hash a null terminated string "src" into "dest" using Blake2b
*/
extern SECStatus BLAKE2B_Hash(unsigned char *dest, const char *src);
/*
** Hash a non-null terminated string "src" into "dest" using Blake2b
*/
extern SECStatus BLAKE2B_HashBuf(unsigned char *output,
const unsigned char *input, PRUint32 inlen);
extern SECStatus BLAKE2B_MAC_HashBuf(unsigned char *output,
const unsigned char *input,
unsigned int inlen,
const unsigned char *key,
unsigned int keylen);
/*
** Create a new Blake2b context
*/
extern BLAKE2BContext *BLAKE2B_NewContext();
/*
** Destroy a Blake2b secure hash context.
** "ctx" the context
** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
extern void BLAKE2B_DestroyContext(BLAKE2BContext *ctx, PRBool freeit);
/*
** Reset a Blake2b context, preparing it for a fresh round of hashing
*/
extern SECStatus BLAKE2B_Begin(BLAKE2BContext *ctx);
extern SECStatus BLAKE2B_MAC_Begin(BLAKE2BContext *ctx, const PRUint8 *key,
const size_t keylen);
/*
** Update the Blake hash function with more data.
*/
extern SECStatus BLAKE2B_Update(BLAKE2BContext *ctx, const unsigned char *in,
unsigned int inlen);
/*
** Finish the Blake hash function. Produce the digested results in "digest"
*/
extern SECStatus BLAKE2B_End(BLAKE2BContext *ctx, unsigned char *out,
unsigned int *digestLen, size_t maxDigestLen);
/*
* Return the size of a buffer needed to flatten the Blake2b Context into
* "ctx" the context
* returns size;
*/
extern unsigned int BLAKE2B_FlattenSize(BLAKE2BContext *ctx);
/*
* Flatten the Blake2b Context into a buffer:
* "ctx" the context
* "space" the buffer to flatten to
* returns status;
*/
extern SECStatus BLAKE2B_Flatten(BLAKE2BContext *ctx, unsigned char *space);
/*
* Resurrect a flattened context into a Blake2b Context
* "space" the buffer of the flattend buffer
* "arg" ptr to void used by cryptographic resurrect
* returns resurected context
*/
extern BLAKE2BContext *BLAKE2B_Resurrect(unsigned char *space, void *arg);
extern void BLAKE2B_Clone(BLAKE2BContext *dest, BLAKE2BContext *src);
/******************************************/
/*
** Pseudo Random Number Generation. FIPS compliance desirable.
......
......@@ -91,25 +91,27 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
/*
* Number of bytes each hash algorithm produces
*/
#define MD2_LENGTH 16 /* Bytes */
#define MD5_LENGTH 16 /* Bytes */
#define SHA1_LENGTH 20 /* Bytes */
#define SHA256_LENGTH 32 /* bytes */
#define SHA384_LENGTH 48 /* bytes */
#define SHA512_LENGTH 64 /* bytes */
#define MD2_LENGTH 16 /* Bytes */
#define MD5_LENGTH 16 /* Bytes */
#define SHA1_LENGTH 20 /* Bytes */
#define SHA256_LENGTH 32 /* bytes */
#define SHA384_LENGTH 48 /* bytes */
#define SHA512_LENGTH 64 /* bytes */
#define BLAKE2B512_LENGTH 64 /* Bytes */
#define HASH_LENGTH_MAX SHA512_LENGTH
/*
* Input block size for each hash algorithm.
*/
#define MD2_BLOCK_LENGTH 64 /* bytes */
#define MD5_BLOCK_LENGTH 64 /* bytes */
#define SHA1_BLOCK_LENGTH 64 /* bytes */
#define SHA224_BLOCK_LENGTH 64 /* bytes */
#define SHA256_BLOCK_LENGTH 64 /* bytes */
#define SHA384_BLOCK_LENGTH 128 /* bytes */
#define SHA512_BLOCK_LENGTH 128 /* bytes */
#define MD2_BLOCK_LENGTH 64 /* bytes */
#define MD5_BLOCK_LENGTH 64 /* bytes */
#define SHA1_BLOCK_LENGTH 64 /* bytes */
#define SHA224_BLOCK_LENGTH 64 /* bytes */
#define SHA256_BLOCK_LENGTH 64 /* bytes */
#define SHA384_BLOCK_LENGTH 128 /* bytes */
#define SHA512_BLOCK_LENGTH 128 /* bytes */
#define BLAKE2B_BLOCK_LENGTH 128 /* Bytes */
#define HASH_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH
#define AES_KEY_WRAP_IV_BYTES 8
......@@ -127,6 +129,8 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
#define NSS_FREEBL_DEFAULT_CHUNKSIZE 2048
#define BLAKE2B_KEY_SIZE 64
/*
* These values come from the initial key size limits from the PKCS #11
* module. They may be arbitrarily adjusted to any value freebl supports.
......@@ -213,6 +217,7 @@ struct SHA512ContextStr;
struct AESKeyWrapContextStr;
struct SEEDContextStr;
struct ChaCha20Poly1305ContextStr;
struct Blake2bContextStr;
typedef struct DESContextStr DESContext;
typedef struct RC2ContextStr RC2Context;
......@@ -232,6 +237,7 @@ typedef struct SHA512ContextStr SHA384Context;
typedef struct AESKeyWrapContextStr AESKeyWrapContext;
typedef struct SEEDContextStr SEEDContext;
typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
typedef struct Blake2bContextStr BLAKE2BContext;
/***************************************************************************
** RSA Public and Private Key structures
......
/* 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/. */
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif
/* This file holds useful functions and macros for crypto code. */
#include "crypto_primitives.h"
/*
* FREEBL_HTONLL(x): swap bytes in a 64-bit integer.
*/
#if defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64))
__inline__ PRUint64
swap8b(PRUint64 value)
{
__asm__("bswapq %0"
: "+r"(value));
return (value);
}
#elif !defined(_MSC_VER)
PRUint64
swap8b(PRUint64 x)
{
PRUint64 t1 = x;
t1 = ((t1 & SHA_MASK8) << 8) | ((t1 >> 8) & SHA_MASK8);
t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16);
return (t1 >> 32) | (t1 << 32);
}
#endif
/* 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/. */
/* This file holds useful functions and macros for crypto code. */
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif
#include <stdlib.h>
#include "prtypes.h"
/* Unfortunately this isn't always set when it should be. */
#if defined(HAVE_LONG_LONG)
/*
* ROTR64/ROTL64(x, n): rotate a 64-bit integer x by n bites to the right/left.
*/
#if defined(_MSC_VER)
#pragma intrinsic(_rotr64, _rotl64)
#define ROTR64(x, n) _rotr64((x), (n))
#define ROTL64(x, n) _rotl64((x), (n))
#else
#define ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
#endif
/*
* FREEBL_HTONLL(x): swap bytes in a 64-bit integer.
*/
#if defined(_MSC_VER)
#pragma intrinsic(_byteswap_uint64)
#define FREEBL_HTONLL(x) _byteswap_uint64(x)
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64))
PRUint64 swap8b(PRUint64 value);
#define FREEBL_HTONLL(x) swap8b(x)
#else
#define SHA_MASK16 0x0000FFFF0000FFFFULL
#define SHA_MASK8 0x00FF00FF00FF00FFULL
PRUint64 swap8b(PRUint64 x);
#define FREEBL_HTONLL(x) swap8b(x)
#endif /* _MSC_VER */
#endif /* HAVE_LONG_LONG */
\ No newline at end of file
......@@ -29,6 +29,7 @@
'files': [
'alghmac.h',
'blapi.h',
'blake2b.h',
'chacha20poly1305.h',
'ec.h',
'ecl/ecl-curve.h',
......
......@@ -8,8 +8,10 @@
'alghmac.c',
'arcfive.c',
'arcfour.c',
'blake2b.c',
'camellia.c',
'chacha20poly1305.c',
'crypto_primitives.c',
'ctr.c',
'cts.c',
'des.c',
......
......@@ -298,9 +298,25 @@ static const struct FREEBLVectorStr vector =
/* End of Version 3.018 */
EC_GetPointSize
EC_GetPointSize,
/* End of Version 3.019 */
BLAKE2B_Hash,
BLAKE2B_HashBuf,
BLAKE2B_MAC_HashBuf,
BLAKE2B_NewContext,
BLAKE2B_DestroyContext,
BLAKE2B_Begin,
BLAKE2B_MAC_Begin,
BLAKE2B_Update,
BLAKE2B_End,
BLAKE2B_FlattenSize,
BLAKE2B_Flatten,
BLAKE2B_Resurrect
/* End of Version 3.020 */
};
const FREEBLVector*
......
......@@ -2124,3 +2124,114 @@ EC_GetPointSize(const ECParams *params)
return SECFailure;
return (vector->p_EC_GetPointSize)(params);
}
SECStatus
BLAKE2B_Hash(unsigned char *dest, const char *src)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) {
return SECFailure;
}
return (vector->p_BLAKE2B_Hash)(dest, src);
}
SECStatus
BLAKE2B_HashBuf(unsigned char *output, const unsigned char *input, PRUint32 inlen)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) {
return SECFailure;
}
return (vector->p_BLAKE2B_HashBuf)(output, input, inlen);
}
SECStatus
BLAKE2B_MAC_HashBuf(unsigned char *output, const unsigned char *input,
unsigned int inlen, const unsigned char *key,
unsigned int keylen)
{