diff options
Diffstat (limited to 'security/nss/lib/freebl/blake2b.c')
-rw-r--r-- | security/nss/lib/freebl/blake2b.c | 430 |
1 files changed, 0 insertions, 430 deletions
diff --git a/security/nss/lib/freebl/blake2b.c b/security/nss/lib/freebl/blake2b.c deleted file mode 100644 index 4099c67e0..000000000 --- a/security/nss/lib/freebl/blake2b.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * blake2b.c - definitions for the 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/. */ - -#ifdef FREEBL_NO_DEPEND -#include "stubs.h" -#endif - -#include "secerr.h" -#include "blapi.h" -#include "blake2b.h" -#include "crypto_primitives.h" - -/** - * This contains the BLAKE2b initialization vectors. - */ -static const uint64_t iv[8] = { - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, - 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -/** - * This contains the table of permutations for blake2b compression function. - */ -static const uint8_t sigma[12][16] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } -}; - -/** - * This function increments the blake2b ctx counter. - */ -void -blake2b_IncrementCounter(BLAKE2BContext* ctx, const uint64_t inc) -{ - ctx->t[0] += inc; - ctx->t[1] += ctx->t[0] < inc; -} - -/** - * This macro implements the blake2b mixing function which mixes two 8-byte - * words from the message into the hash. - */ -#define G(a, b, c, d, x, y) \ - a += b + x; \ - d = ROTR64(d ^ a, 32); \ - c += d; \ - b = ROTR64(b ^ c, 24); \ - a += b + y; \ - d = ROTR64(d ^ a, 16); \ - c += d; \ - b = ROTR64(b ^ c, 63) - -#define ROUND(i) \ - G(v[0], v[4], v[8], v[12], m[sigma[i][0]], m[sigma[i][1]]); \ - G(v[1], v[5], v[9], v[13], m[sigma[i][2]], m[sigma[i][3]]); \ - G(v[2], v[6], v[10], v[14], m[sigma[i][4]], m[sigma[i][5]]); \ - G(v[3], v[7], v[11], v[15], m[sigma[i][6]], m[sigma[i][7]]); \ - G(v[0], v[5], v[10], v[15], m[sigma[i][8]], m[sigma[i][9]]); \ - G(v[1], v[6], v[11], v[12], m[sigma[i][10]], m[sigma[i][11]]); \ - G(v[2], v[7], v[8], v[13], m[sigma[i][12]], m[sigma[i][13]]); \ - G(v[3], v[4], v[9], v[14], m[sigma[i][14]], m[sigma[i][15]]) - -/** - * The blake2b compression function which takes a full 128-byte chunk of the - * input message and mixes it into the ongoing ctx array, i.e., permute the - * ctx while xoring in the block of data. - */ -void -blake2b_Compress(BLAKE2BContext* ctx, const uint8_t* block) -{ - size_t i; - uint64_t v[16], m[16]; - - PORT_Memcpy(m, block, BLAKE2B_BLOCK_LENGTH); -#if !defined(IS_LITTLE_ENDIAN) - for (i = 0; i < 16; ++i) { - m[i] = FREEBL_HTONLL(m[i]); - } -#endif - - PORT_Memcpy(v, ctx->h, 8 * 8); - PORT_Memcpy(v + 8, iv, 8 * 8); - - v[12] ^= ctx->t[0]; - v[13] ^= ctx->t[1]; - v[14] ^= ctx->f; - - ROUND(0); - ROUND(1); - ROUND(2); - ROUND(3); - ROUND(4); - ROUND(5); - ROUND(6); - ROUND(7); - ROUND(8); - ROUND(9); - ROUND(10); - ROUND(11); - - for (i = 0; i < 8; i++) { - ctx->h[i] ^= v[i] ^ v[i + 8]; - } -} - -/** - * This function can be used for both keyed and unkeyed version. - */ -BLAKE2BContext* -BLAKE2B_NewContext() -{ - return PORT_ZNew(BLAKE2BContext); -} - -/** - * Zero and free the context and can be used for both keyed and unkeyed version. - */ -void -BLAKE2B_DestroyContext(BLAKE2BContext* ctx, PRBool freeit) -{ - PORT_Memset(ctx, 0, sizeof(*ctx)); - if (freeit) { - PORT_Free(ctx); - } -} - -/** - * This function initializes blake2b ctx and can be used for both keyed and - * unkeyed version. It also checks ctx and sets error states. - */ -static SECStatus -blake2b_Begin(BLAKE2BContext* ctx, uint8_t outlen, const uint8_t* key, - size_t keylen) -{ - PORT_Assert(ctx != NULL); - if (!ctx) { - goto failure; - } - if (outlen == 0 || outlen > BLAKE2B512_LENGTH) { - goto failure; - } - if (key && keylen > BLAKE2B_KEY_SIZE) { - goto failure; - } - /* Note: key can be null if it's unkeyed. */ - if ((key == NULL && keylen > 0) || keylen > BLAKE2B_KEY_SIZE || - (key != NULL && keylen == 0)) { - goto failure; - } - - /* Mix key size(keylen) and desired hash length(outlen) into h0 */ - uint64_t param = outlen ^ (keylen << 8) ^ (1 << 16) ^ (1 << 24); - PORT_Memcpy(ctx->h, iv, 8 * 8); - ctx->h[0] ^= param; - ctx->outlen = outlen; - - /* This updates the context for only the keyed version */ - if (keylen > 0 && keylen <= BLAKE2B_KEY_SIZE && key) { - uint8_t block[BLAKE2B_BLOCK_LENGTH] = { 0 }; - PORT_Memcpy(block, key, keylen); - BLAKE2B_Update(ctx, block, BLAKE2B_BLOCK_LENGTH); - PORT_Memset(block, 0, BLAKE2B_BLOCK_LENGTH); - } - - return SECSuccess; - -failure: - PORT_Memset(&ctx, 0, sizeof(ctx)); - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; -} - -SECStatus -BLAKE2B_Begin(BLAKE2BContext* ctx) -{ - return blake2b_Begin(ctx, BLAKE2B512_LENGTH, NULL, 0); -} - -SECStatus -BLAKE2B_MAC_Begin(BLAKE2BContext* ctx, const PRUint8* key, const size_t keylen) -{ - PORT_Assert(key != NULL); - if (!key) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - return blake2b_Begin(ctx, BLAKE2B512_LENGTH, (const uint8_t*)key, keylen); -} - -static void -blake2b_IncrementCompress(BLAKE2BContext* ctx, size_t blockLength, - const unsigned char* input) -{ - blake2b_IncrementCounter(ctx, blockLength); - blake2b_Compress(ctx, input); -} - -/** - * This function updates blake2b ctx and can be used for both keyed and unkeyed - * version. - */ -SECStatus -BLAKE2B_Update(BLAKE2BContext* ctx, const unsigned char* in, - unsigned int inlen) -{ - size_t left = ctx->buflen; - size_t fill = BLAKE2B_BLOCK_LENGTH - left; - - /* Nothing to do if there's nothing. */ - if (inlen == 0) { - return SECSuccess; - } - - PORT_Assert(ctx != NULL); - PORT_Assert(in != NULL); - PORT_Assert(left <= BLAKE2B_BLOCK_LENGTH); - if (!ctx || !in) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* Is this a reused context? */ - if (ctx->f) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (inlen > fill) { - if (ctx->buflen) { - /* There's some remaining data in ctx->buf that we have to prepend - * to in. */ - PORT_Memcpy(ctx->buf + left, in, fill); - ctx->buflen = 0; - blake2b_IncrementCompress(ctx, BLAKE2B_BLOCK_LENGTH, ctx->buf); - in += fill; - inlen -= fill; - } - while (inlen > BLAKE2B_BLOCK_LENGTH) { - blake2b_IncrementCompress(ctx, BLAKE2B_BLOCK_LENGTH, in); - in += BLAKE2B_BLOCK_LENGTH; - inlen -= BLAKE2B_BLOCK_LENGTH; - } - } - - /* Store the remaining data from in in ctx->buf to process later. - * Note that ctx->buflen can be BLAKE2B_BLOCK_LENGTH. We can't process that - * here because we have to update ctx->f before compressing the last block. - */ - PORT_Assert(inlen <= BLAKE2B_BLOCK_LENGTH); - PORT_Memcpy(ctx->buf + ctx->buflen, in, inlen); - ctx->buflen += inlen; - - return SECSuccess; -} - -/** - * This function finalizes ctx, pads final block and stores hash. - * It can be used for both keyed and unkeyed version. - */ -SECStatus -BLAKE2B_End(BLAKE2BContext* ctx, unsigned char* out, - unsigned int* digestLen, size_t maxDigestLen) -{ - size_t i; - unsigned int outlen = PR_MIN(BLAKE2B512_LENGTH, maxDigestLen); - - /* Argument checks */ - if (!ctx || !out) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* Sanity check against outlen in context. */ - if (ctx->outlen < outlen) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* Is this a reused context? */ - if (ctx->f != 0) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* Process the remaining data from ctx->buf (padded with 0). */ - blake2b_IncrementCounter(ctx, ctx->buflen); - /* BLAKE2B_BLOCK_LENGTH - ctx->buflen can be 0. */ - PORT_Memset(ctx->buf + ctx->buflen, 0, BLAKE2B_BLOCK_LENGTH - ctx->buflen); - ctx->f = UINT64_MAX; - blake2b_Compress(ctx, ctx->buf); - - /* Write out the blake2b context(ctx). */ - for (i = 0; i < outlen; ++i) { - out[i] = ctx->h[i / 8] >> ((i % 8) * 8); - } - - if (digestLen) { - *digestLen = outlen; - } - - return SECSuccess; -} - -SECStatus -blake2b_HashBuf(uint8_t* output, const uint8_t* input, uint8_t outlen, - size_t inlen, const uint8_t* key, size_t keylen) -{ - SECStatus rv = SECFailure; - BLAKE2BContext ctx = { { 0 } }; - - if (inlen != 0) { - PORT_Assert(input != NULL); - if (input == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto done; - } - } - - PORT_Assert(output != NULL); - if (output == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto done; - } - - if (blake2b_Begin(&ctx, outlen, key, keylen) != SECSuccess) { - goto done; - } - - if (BLAKE2B_Update(&ctx, input, inlen) != SECSuccess) { - goto done; - } - - if (BLAKE2B_End(&ctx, output, NULL, outlen) != SECSuccess) { - goto done; - } - rv = SECSuccess; - -done: - PORT_Memset(&ctx, 0, sizeof ctx); - return rv; -} - -SECStatus -BLAKE2B_Hash(unsigned char* dest, const char* src) -{ - return blake2b_HashBuf(dest, (const unsigned char*)src, BLAKE2B512_LENGTH, - PORT_Strlen(src), NULL, 0); -} - -SECStatus -BLAKE2B_HashBuf(unsigned char* output, const unsigned char* input, PRUint32 inlen) -{ - return blake2b_HashBuf(output, input, BLAKE2B512_LENGTH, inlen, NULL, 0); -} - -SECStatus -BLAKE2B_MAC_HashBuf(unsigned char* output, const unsigned char* input, - unsigned int inlen, const unsigned char* key, - unsigned int keylen) -{ - PORT_Assert(key != NULL); - if (!key && keylen <= BLAKE2B_KEY_SIZE) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - return blake2b_HashBuf(output, input, BLAKE2B512_LENGTH, inlen, key, keylen); -} - -unsigned int -BLAKE2B_FlattenSize(BLAKE2BContext* ctx) -{ - return sizeof(BLAKE2BContext); -} - -SECStatus -BLAKE2B_Flatten(BLAKE2BContext* ctx, unsigned char* space) -{ - PORT_Assert(space != NULL); - if (!space) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - PORT_Memcpy(space, ctx, sizeof(BLAKE2BContext)); - return SECSuccess; -} - -BLAKE2BContext* -BLAKE2B_Resurrect(unsigned char* space, void* arg) -{ - PORT_Assert(space != NULL); - if (!space) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - BLAKE2BContext* ctx = BLAKE2B_NewContext(); - if (ctx == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - PORT_Memcpy(ctx, space, sizeof(BLAKE2BContext)); - return ctx; -} - -void -BLAKE2B_Clone(BLAKE2BContext* dest, BLAKE2BContext* src) -{ - PORT_Assert(dest != NULL); - PORT_Assert(src != NULL); - if (!dest || !src) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return; - } - PORT_Memcpy(dest, src, sizeof(BLAKE2BContext)); -} |