int sha256_test(void) { Sha256 sha; byte hash[SHA256_DIGEST_SIZE]; testVector a, b; testVector test_sha[2]; int ret; int times = sizeof(test_sha) / sizeof(struct testVector), i; a.input = "abc"; a.output = "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22" "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00" "\x15\xAD"; a.inLen = strlen(a.input); a.outLen = strlen(a.output); b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; b.output = "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" "\x06\xC1"; b.inLen = strlen(b.input); b.outLen = strlen(b.output); test_sha[0] = a; test_sha[1] = b; ret = wc_InitSha256(&sha); if (ret != 0) return ret; for (i = 0; i < times; ++i) { ret = wc_Sha256Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); if (ret != 0) return ret; ret = wc_Sha256Final(&sha, hash); if (ret != 0) return ret; if (memcmp(hash, test_sha[i].output, SHA256_DIGEST_SIZE) != 0) return -10 - i; } return 0; }
void file_test(const char* file, byte* check) { FILE* f; int i = 0, j, ret; Sha256 sha256; byte buf[1024]; byte shasum[SHA256_DIGEST_SIZE]; ret = wc_InitSha256(&sha256); if (ret != 0) { printf("Can't wc_InitSha256 %d\n", ret); return; } if( !( f = fopen( file, "rb" ) )) { printf("Can't open %s\n", file); return; } while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 ) { ret = wc_Sha256Update(&sha256, buf, i); if (ret != 0) { printf("Can't wc_Sha256Update %d\n", ret); fclose(f); return; } } ret = wc_Sha256Final(&sha256, shasum); if (ret != 0) { printf("Can't wc_Sha256Final %d\n", ret); fclose(f); return; } memcpy(check, shasum, sizeof(shasum)); for(j = 0; j < SHA256_DIGEST_SIZE; ++j ) printf( "%02x", shasum[j] ); printf(" %s\n", file); fclose(f); }
void sha256_rsa_pubkey ( unsigned char hash[SHA256_DIGEST_SIZE], RsaKey* key ) { // Expect a 2048 bit RSA key. assert(key->n.used == 32); uint8_t buf[1024]; /* SetRsaPublicKey() only exports n and e without wrapping them in additional ASN.1 (PKCS#1). */ int pub_rsa_key_der_len = SetRsaPublicKey(buf, key, sizeof(buf), 0); assert(pub_rsa_key_der_len == 270); Sha256 sha; wc_InitSha256(&sha); wc_Sha256Update(&sha, buf, pub_rsa_key_der_len); wc_Sha256Final(&sha, hash); }
/* Prepare a seed from the selected pools. Helper function for re-seeding. */ static int fortuna_extract_seed(uint8_t *seed_buffer, int buffer_size) { int i = 0; int hashes_added = 0; for (i = 0; i < FORTUNA_POOL_COUNT; i++) { if (((i % 8) == 0) || (fortuna_generator.counter->values[0] & (1 << ((i - 1) % 8)))) { /* Use nth pool every (2^n)th reseed (so p1 every other time, p2 every 4th... */ if ((hashes_added + 1) * FORTUNA_HASH_SIZE <= buffer_size) { /* Extract final hash for given pool, and put in appropriate part of seed buffer */ wc_Sha256Final(&(fortuna_generator.pool[i]), seed_buffer + (FORTUNA_HASH_SIZE * hashes_added)); hashes_added++; } else { /* Buffer not big enough */ return 0; } } } return (hashes_added * FORTUNA_HASH_SIZE); /* Actual size of seed */ }
/* check mcapi sha256 against internal */ static int check_sha256(void) { CRYPT_SHA256_CTX mcSha256; Sha256 defSha256; int ret; byte mcDigest[CRYPT_SHA256_DIGEST_SIZE]; byte defDigest[SHA256_DIGEST_SIZE]; CRYPT_SHA256_Initialize(&mcSha256); ret = wc_InitSha256(&defSha256); if (ret != 0) { printf("sha256 init default failed\n"); return -1; } CRYPT_SHA256_DataAdd(&mcSha256, ourData, OUR_DATA_SIZE); ret = wc_Sha256Update(&defSha256, ourData, OUR_DATA_SIZE); if (ret != 0) { printf("sha256 update default failed\n"); return -1; } CRYPT_SHA256_Finalize(&mcSha256, mcDigest); ret = wc_Sha256Final(&defSha256, defDigest); if (ret != 0) { printf("sha256 final default failed\n"); return -1; } if (memcmp(mcDigest, defDigest, CRYPT_SHA256_DIGEST_SIZE) != 0) { printf("sha256 final memcmp fialed\n"); return -1; } printf("sha256 mcapi test passed\n"); return 0; }
/* Re-seed the generator. Called when enough data has been used from the current 'run' */ static int fortuna_reseed(uint8_t *seed, uint8_t seed_size) { uint8_t *sha_input = NULL; sha_input = (uint8_t *)kalloc(seed_size + FORTUNA_ENCRYPT_KEY_SIZE); /* Seed size + 256b of current SHA hash key */ if (NULL == sha_input) { /* Failed to alloc, don't increment counter */ return 0; } else { memcpy(sha_input, fortuna_generator.key, FORTUNA_ENCRYPT_KEY_SIZE); /* Current key */ memcpy(sha_input + FORTUNA_ENCRYPT_KEY_SIZE, seed, seed_size); /* New seed */ } wc_InitSha256(fortuna_generator.sha); wc_Sha256Update(fortuna_generator.sha, sha_input, seed_size + 32); wc_Sha256Final(fortuna_generator.sha, fortuna_generator.key); fortuna_increment_counter(fortuna_generator.counter); kfree(sha_input); return 1; }
/* helper for PKCS12_PBKDF(), does hash operation */ int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen, byte* Ai, word32 u, int iterations) { int i; int ret = 0; if (buffer == NULL || Ai == NULL) return BAD_FUNC_ARG; switch (hashType) { #ifndef NO_MD5 case MD5: { Md5 md5; wc_InitMd5(&md5); wc_Md5Update(&md5, buffer, totalLen); wc_Md5Final(&md5, Ai); for (i = 1; i < iterations; i++) { wc_Md5Update(&md5, Ai, u); wc_Md5Final(&md5, Ai); } } break; #endif /* NO_MD5 */ #ifndef NO_SHA case SHA: { Sha sha; ret = wc_InitSha(&sha); if (ret != 0) break; wc_ShaUpdate(&sha, buffer, totalLen); wc_ShaFinal(&sha, Ai); for (i = 1; i < iterations; i++) { wc_ShaUpdate(&sha, Ai, u); wc_ShaFinal(&sha, Ai); } } break; #endif /* NO_SHA */ #ifndef NO_SHA256 case SHA256: { Sha256 sha256; ret = wc_InitSha256(&sha256); if (ret != 0) break; ret = wc_Sha256Update(&sha256, buffer, totalLen); if (ret != 0) break; ret = wc_Sha256Final(&sha256, Ai); if (ret != 0) break; for (i = 1; i < iterations; i++) { ret = wc_Sha256Update(&sha256, Ai, u); if (ret != 0) break; ret = wc_Sha256Final(&sha256, Ai); if (ret != 0) break; } } break; #endif /* NO_SHA256 */ #ifdef WOLFSSL_SHA512 case SHA512: { Sha512 sha512; ret = wc_InitSha512(&sha512); if (ret != 0) break; ret = wc_Sha512Update(&sha512, buffer, totalLen); if (ret != 0) break; ret = wc_Sha512Final(&sha512, Ai); if (ret != 0) break; for (i = 1; i < iterations; i++) { ret = wc_Sha512Update(&sha512, Ai, u); if (ret != 0) break; ret = wc_Sha512Final(&sha512, Ai); if (ret != 0) break; } } break; #endif /* WOLFSSL_SHA512 */ default: ret = BAD_FUNC_ARG; break; } return ret; }
/* * benchmarking funciton */ int wolfCLU_benchmark(int timer, int* option) { int i = 0; /* A looping variable */ int loop = 1; /* benchmarking loop */ int64_t blocks = 0; /* blocks used during benchmarking */ #ifndef NO_AES Aes aes; /* aes declaration */ #endif #ifndef NO_DES3 Des3 des3; /* 3des declaration */ #endif RNG rng; /* random number generator */ int ret = 0; /* return variable */ double stop = 0.0; /* stop breaks loop */ double start; /* start time */ double currTime; /* current time*/ ALIGN16 byte* plain; /* plain text */ ALIGN16 byte* cipher; /* cipher */ ALIGN16 byte* key; /* key for testing */ ALIGN16 byte* iv; /* iv for initial encoding */ byte* digest; /* message digest */ wc_InitRng(&rng); signal(SIGALRM, wolfCLU_stop); i = 0; #ifndef NO_AES /* aes test */ if (option[i] == 1) { plain = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_AesSetKey(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); while (loop) { wc_AesCbcEncrypt(&aes, cipher, plain, AES_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("\n"); printf("AES-CBC "); wolfCLU_stats(start, AES_BLOCK_SIZE, blocks); XMEMSET(plain, 0, AES_BLOCK_SIZE); XMEMSET(cipher, 0, AES_BLOCK_SIZE); XMEMSET(key, 0, AES_BLOCK_SIZE); XMEMSET(iv, 0, AES_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef WOLFSSL_AES_COUNTER /* aes-ctr test */ if (option[i] == 1) { plain = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_AesSetKeyDirect(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); while (loop) { wc_AesCtrEncrypt(&aes, cipher, plain, AES_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("AES-CTR "); wolfCLU_stats(start, AES_BLOCK_SIZE, blocks); XMEMSET(plain, 0, AES_BLOCK_SIZE); XMEMSET(cipher, 0, AES_BLOCK_SIZE); XMEMSET(key, 0, AES_BLOCK_SIZE); XMEMSET(iv, 0, AES_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_DES3 /* 3des test */ if (option[i] == 1) { plain = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, DES3_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, DES3_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, DES3_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, DES3_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION); while (loop) { wc_Des3_CbcEncrypt(&des3, cipher, plain, DES3_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("3DES "); wolfCLU_stats(start, DES3_BLOCK_SIZE, blocks); XMEMSET(plain, 0, DES3_BLOCK_SIZE); XMEMSET(cipher, 0, DES3_BLOCK_SIZE); XMEMSET(key, 0, DES3_BLOCK_SIZE); XMEMSET(iv, 0, DES3_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef HAVE_CAMELLIA #define CAM_SZ CAMELLIA_BLOCK_SIZE /* camellia test */ if (option[i] == 1) { Camellia camellia; plain = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, CAMELLIA_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, CAMELLIA_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, CAMELLIA_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, CAMELLIA_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_CamelliaSetKey(&camellia, key, CAMELLIA_BLOCK_SIZE, iv); while (loop) { wc_CamelliaCbcEncrypt(&camellia, cipher, plain, CAMELLIA_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("Camellia "); wolfCLU_stats(start, CAMELLIA_BLOCK_SIZE, blocks); XMEMSET(plain, 0, CAMELLIA_BLOCK_SIZE); XMEMSET(cipher, 0, CAMELLIA_BLOCK_SIZE); XMEMSET(key, 0, CAMELLIA_BLOCK_SIZE); XMEMSET(iv, 0, CAMELLIA_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_MD5 /* md5 test */ if (option[i] == 1) { Md5 md5; digest = XMALLOC(MD5_DIGEST_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitMd5(&md5); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Md5Update(&md5, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Md5Final(&md5, digest); printf("MD5 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, MD5_DIGEST_SIZE); wolfCLU_freeBins(digest, plain, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_SHA /* sha test */ if (option[i] == 1) { Sha sha; digest = XMALLOC(SHA_DIGEST_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha(&sha); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_ShaUpdate(&sha, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_ShaFinal(&sha, digest); printf("Sha "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_SHA256 #define SHA256_SZ SHA256_DIGEST_SIZE /* sha256 test */ if (option[i] == 1) { Sha256 sha256; digest = XMALLOC(SHA256_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha256(&sha256); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Sha256Update(&sha256, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Sha256Final(&sha256, digest); printf("Sha256 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA256_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); /* resets used for debug, uncomment if needed */ blocks = 0; loop = 1; } i++; #endif #ifdef WOLFSSL_SHA384 #define SHA384_SZ SHA384_DIGEST_SIZE /* sha384 test */ if (option[i] == 1) { Sha384 sha384; digest = XMALLOC(SHA384_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha384(&sha384); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Sha384Update(&sha384, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Sha384Final(&sha384, digest); printf("Sha384 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA384_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef WOLFSSL_SHA512 #define SHA512_SZ SHA512_DIGEST_SIZE /* sha512 test */ if (option[i] == 1) { Sha512 sha512; digest = XMALLOC(SHA512_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha512(&sha512); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Sha512Update(&sha512, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Sha512Final(&sha512, digest); printf("Sha512 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA512_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef HAVE_BLAKE2 /* blake2b test */ if (option[i] == 1) { Blake2b b2b; digest = XMALLOC(BLAKE_DIGEST_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitBlake2b(&b2b, BLAKE_DIGEST_SIZE); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Blake2bUpdate(&b2b, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Blake2bFinal(&b2b, digest, BLAKE_DIGEST_SIZE); printf("Blake2b "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, BLAKE_DIGEST_SIZE); wolfCLU_freeBins(digest, plain, NULL, NULL, NULL); } #endif return ret; }
int wc_HmacFinal(Hmac* hmac, byte* hash) { int ret; if (hmac == NULL || hash == NULL) { return BAD_FUNC_ARG; } #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { int hashLen = wc_HmacSizeByType(hmac->macType); if (hashLen <= 0) return hashLen; #if defined(HAVE_CAVIUM) return NitroxHmacFinal(hmac, hmac->macType, hash, hashLen); #elif defined(HAVE_INTEL_QA) return IntelQaHmac(&hmac->asyncDev, hmac->macType, (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen); #endif } #endif /* WOLFSSL_ASYNC_CRYPT */ if (!hmac->innerHashKeyed) { ret = HmacKeyInnerHash(hmac); if (ret != 0) return ret; } switch (hmac->macType) { #ifndef NO_MD5 case MD5: ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad, MD5_BLOCK_SIZE); if (ret != 0) break; ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash, MD5_DIGEST_SIZE); if (ret != 0) break; ret = wc_Md5Final(&hmac->hash.md5, hash); break; #endif /* !NO_MD5 */ #ifndef NO_SHA case SHA: ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad, SHA_BLOCK_SIZE); if (ret != 0) break; ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash, SHA_DIGEST_SIZE); if (ret != 0) break; ret = wc_ShaFinal(&hmac->hash.sha, hash); break; #endif /* !NO_SHA */ #ifdef WOLFSSL_SHA224 case SHA224: { ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad, SHA224_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash, SHA224_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha224Final(&hmac->hash.sha224, hash); if (ret != 0) break; } break; #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 case SHA256: ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad, SHA256_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash, SHA256_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha256Final(&hmac->hash.sha256, hash); break; #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA384 case SHA384: ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad, SHA384_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash, SHA384_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha384Final(&hmac->hash.sha384, hash); break; #endif /* WOLFSSL_SHA384 */ case SHA512: ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad, SHA512_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash, SHA512_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha512Final(&hmac->hash.sha512, hash); break; #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*)hmac->innerHash, BLAKE2B_256); if (ret != 0) break; ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->opad, BLAKE2B_BLOCKBYTES); if (ret != 0) break; ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->innerHash, BLAKE2B_256); if (ret != 0) break; ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); break; #endif /* HAVE_BLAKE2 */ default: ret = BAD_FUNC_ARG; break; } if (ret == 0) { hmac->innerHashKeyed = 0; } return ret; }
int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { byte* ip; byte* op; word32 i, hmac_block_size = 0; int ret = 0; void* heap = NULL; if (hmac == NULL || (key == NULL && length != 0) || !(type == MD5 || type == SHA || type == SHA256 || type == SHA384 || type == SHA512 || type == BLAKE2B_ID || type == SHA224)) { return BAD_FUNC_ARG; } hmac->innerHashKeyed = 0; hmac->macType = (byte)type; #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { #if defined(HAVE_CAVIUM) if (length > HMAC_BLOCK_SIZE) { return WC_KEY_SIZE_E; } if (key != NULL) { XMEMCPY(hmac->ipad, key, length); } hmac->keyLen = (word16)length; return 0; /* nothing to do here */ #endif /* HAVE_CAVIUM */ } #endif /* WOLFSSL_ASYNC_CRYPT */ ret = _InitHmac(hmac, type, heap); if (ret != 0) return ret; #ifdef HAVE_FIPS if (length < HMAC_FIPS_MIN_KEY) return HMAC_MIN_KEYLEN_E; #endif ip = (byte*)hmac->ipad; op = (byte*)hmac->opad; switch (hmac->macType) { #ifndef NO_MD5 case MD5: hmac_block_size = MD5_BLOCK_SIZE; if (length <= MD5_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Md5Update(&hmac->hash.md5, key, length); if (ret != 0) break; ret = wc_Md5Final(&hmac->hash.md5, ip); if (ret != 0) break; length = MD5_DIGEST_SIZE; } break; #endif /* !NO_MD5 */ #ifndef NO_SHA case SHA: hmac_block_size = SHA_BLOCK_SIZE; if (length <= SHA_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_ShaUpdate(&hmac->hash.sha, key, length); if (ret != 0) break; ret = wc_ShaFinal(&hmac->hash.sha, ip); if (ret != 0) break; length = SHA_DIGEST_SIZE; } break; #endif /* !NO_SHA */ #ifdef WOLFSSL_SHA224 case SHA224: { hmac_block_size = SHA224_BLOCK_SIZE; if (length <= SHA224_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha224Update(&hmac->hash.sha224, key, length); if (ret != 0) break; ret = wc_Sha224Final(&hmac->hash.sha224, ip); if (ret != 0) break; length = SHA224_DIGEST_SIZE; } } break; #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 case SHA256: hmac_block_size = SHA256_BLOCK_SIZE; if (length <= SHA256_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha256Update(&hmac->hash.sha256, key, length); if (ret != 0) break; ret = wc_Sha256Final(&hmac->hash.sha256, ip); if (ret != 0) break; length = SHA256_DIGEST_SIZE; } break; #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA384 case SHA384: hmac_block_size = SHA384_BLOCK_SIZE; if (length <= SHA384_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha384Update(&hmac->hash.sha384, key, length); if (ret != 0) break; ret = wc_Sha384Final(&hmac->hash.sha384, ip); if (ret != 0) break; length = SHA384_DIGEST_SIZE; } break; #endif /* WOLFSSL_SHA384 */ case SHA512: hmac_block_size = SHA512_BLOCK_SIZE; if (length <= SHA512_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha512Update(&hmac->hash.sha512, key, length); if (ret != 0) break; ret = wc_Sha512Final(&hmac->hash.sha512, ip); if (ret != 0) break; length = SHA512_DIGEST_SIZE; } break; #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_BLAKE2 case BLAKE2B_ID: hmac_block_size = BLAKE2B_BLOCKBYTES; if (length <= BLAKE2B_BLOCKBYTES) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length); if (ret != 0) break; ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); if (ret != 0) break; length = BLAKE2B_256; } break; #endif /* HAVE_BLAKE2 */ default: return BAD_FUNC_ARG; } #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { #if defined(HAVE_INTEL_QA) if (length > hmac_block_size) length = hmac_block_size; /* update key length */ hmac->keyLen = (word16)length; return ret; /* no need to pad below */ #endif } #endif if (ret == 0) { if (length < hmac_block_size) XMEMSET(ip + length, 0, hmac_block_size - length); for(i = 0; i < hmac_block_size; i++) { op[i] = ip[i] ^ OPAD; ip[i] ^= IPAD; } } return ret; }
int wc_HmacFinal(Hmac* hmac, byte* hash) { int ret; #ifdef HAVE_CAVIUM if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) return HmacCaviumFinal(hmac, hash); #endif if (!hmac->innerHashKeyed) { ret = HmacKeyInnerHash(hmac); if (ret != 0) return ret; } switch (hmac->macType) { #ifndef NO_MD5 case MD5: { wc_Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); wc_Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); wc_Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE); wc_Md5Final(&hmac->hash.md5, hash); } break; #endif #ifndef NO_SHA case SHA: { wc_ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); wc_ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); wc_ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE); wc_ShaFinal(&hmac->hash.sha, hash); } break; #endif #ifndef NO_SHA256 case SHA256: { ret = wc_Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); if (ret != 0) return ret; ret = wc_Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, SHA256_BLOCK_SIZE); if (ret != 0) return ret; ret = wc_Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); if (ret != 0) return ret; ret = wc_Sha256Final(&hmac->hash.sha256, hash); if (ret != 0) return ret; } break; #endif #ifdef WOLFSSL_SHA384 case SHA384: { ret = wc_Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); if (ret != 0) return ret; ret = wc_Sha384Update(&hmac->hash.sha384, (byte*) hmac->opad, SHA384_BLOCK_SIZE); if (ret != 0) return ret; ret = wc_Sha384Update(&hmac->hash.sha384, (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); if (ret != 0) return ret; ret = wc_Sha384Final(&hmac->hash.sha384, hash); if (ret != 0) return ret; } break; #endif #ifdef WOLFSSL_SHA512 case SHA512: { ret = wc_Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash); if (ret != 0) return ret; ret = wc_Sha512Update(&hmac->hash.sha512, (byte*) hmac->opad, SHA512_BLOCK_SIZE); if (ret != 0) return ret; ret = wc_Sha512Update(&hmac->hash.sha512, (byte*) hmac->innerHash, SHA512_DIGEST_SIZE); if (ret != 0) return ret; ret = wc_Sha512Final(&hmac->hash.sha512, hash); if (ret != 0) return ret; } break; #endif #ifdef HAVE_BLAKE2 case BLAKE2B_ID: { ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, BLAKE2B_256); if (ret != 0) return ret; ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->opad, BLAKE2B_BLOCKBYTES); if (ret != 0) return ret; ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->innerHash, BLAKE2B_256); if (ret != 0) return ret; ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); if (ret != 0) return ret; } break; #endif default: break; } hmac->innerHashKeyed = 0; return 0; }
int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { byte* ip = (byte*) hmac->ipad; byte* op = (byte*) hmac->opad; word32 i, hmac_block_size = 0; int ret; #ifdef HAVE_CAVIUM if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) return HmacCaviumSetKey(hmac, type, key, length); #endif ret = InitHmac(hmac, type); if (ret != 0) return ret; #ifdef HAVE_FIPS if (length < HMAC_FIPS_MIN_KEY) return HMAC_MIN_KEYLEN_E; #endif switch (hmac->macType) { #ifndef NO_MD5 case MD5: { hmac_block_size = MD5_BLOCK_SIZE; if (length <= MD5_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { wc_Md5Update(&hmac->hash.md5, key, length); wc_Md5Final(&hmac->hash.md5, ip); length = MD5_DIGEST_SIZE; } } break; #endif #ifndef NO_SHA case SHA: { hmac_block_size = SHA_BLOCK_SIZE; if (length <= SHA_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { wc_ShaUpdate(&hmac->hash.sha, key, length); wc_ShaFinal(&hmac->hash.sha, ip); length = SHA_DIGEST_SIZE; } } break; #endif #ifndef NO_SHA256 case SHA256: { hmac_block_size = SHA256_BLOCK_SIZE; if (length <= SHA256_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { ret = wc_Sha256Update(&hmac->hash.sha256, key, length); if (ret != 0) return ret; ret = wc_Sha256Final(&hmac->hash.sha256, ip); if (ret != 0) return ret; length = SHA256_DIGEST_SIZE; } } break; #endif #ifdef WOLFSSL_SHA384 case SHA384: { hmac_block_size = SHA384_BLOCK_SIZE; if (length <= SHA384_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { ret = wc_Sha384Update(&hmac->hash.sha384, key, length); if (ret != 0) return ret; ret = wc_Sha384Final(&hmac->hash.sha384, ip); if (ret != 0) return ret; length = SHA384_DIGEST_SIZE; } } break; #endif #ifdef WOLFSSL_SHA512 case SHA512: { hmac_block_size = SHA512_BLOCK_SIZE; if (length <= SHA512_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { ret = wc_Sha512Update(&hmac->hash.sha512, key, length); if (ret != 0) return ret; ret = wc_Sha512Final(&hmac->hash.sha512, ip); if (ret != 0) return ret; length = SHA512_DIGEST_SIZE; } } break; #endif #ifdef HAVE_BLAKE2 case BLAKE2B_ID: { hmac_block_size = BLAKE2B_BLOCKBYTES; if (length <= BLAKE2B_BLOCKBYTES) { XMEMCPY(ip, key, length); } else { ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length); if (ret != 0) return ret; ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); if (ret != 0) return ret; length = BLAKE2B_256; } } break; #endif default: return BAD_FUNC_ARG; } if (length < hmac_block_size) XMEMSET(ip + length, 0, hmac_block_size - length); for(i = 0; i < hmac_block_size; i++) { op[i] = ip[i] ^ OPAD; ip[i] ^= IPAD; } return 0; }
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V) { int ret = DRBG_FAILURE; byte data[DRBG_SEED_LEN]; int i; int len; word32 checkBlock; Sha256 sha; DECLARE_VAR(digest, byte, SHA256_DIGEST_SIZE, drbg->heap); /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for * the continuous test. */ if (outSz == 0) outSz = 1; len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); XMEMCPY(data, V, sizeof(data)); for (i = 0; i < len; i++) { #ifdef WOLFSSL_ASYNC_CRYPT ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId); #else ret = wc_InitSha256(&sha); #endif if (ret == 0) ret = wc_Sha256Update(&sha, data, sizeof(data)); if (ret == 0) ret = wc_Sha256Final(&sha, digest); wc_Sha256Free(&sha); if (ret == 0) { XMEMCPY(&checkBlock, digest, sizeof(word32)); if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) { if (drbg->matchCount == 1) { return DRBG_CONT_FAILURE; } else { if (i == len) { len++; } drbg->matchCount = 1; } } else { drbg->matchCount = 0; drbg->lastBlock = checkBlock; } if (out != NULL && outSz != 0) { if (outSz >= OUTPUT_BLOCK_LEN) { XMEMCPY(out, digest, OUTPUT_BLOCK_LEN); outSz -= OUTPUT_BLOCK_LEN; out += OUTPUT_BLOCK_LEN; array_add_one(data, DRBG_SEED_LEN); } else { XMEMCPY(out, digest, outSz); outSz = 0; } } } } ForceZero(data, sizeof(data)); FREE_VAR(digest, drbg->heap); return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE; }
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type, const byte* inA, word32 inASz, const byte* inB, word32 inBSz) { int ret = DRBG_FAILURE; byte ctr; int i; int len; word32 bits = (outSz * 8); /* reverse byte order */ Sha256 sha; DECLARE_VAR(digest, byte, SHA256_DIGEST_SIZE, drbg->heap); (void)drbg; #ifdef WOLFSSL_ASYNC_CRYPT if (digest == NULL) return DRBG_FAILURE; #endif #ifdef LITTLE_ENDIAN_ORDER bits = ByteReverseWord32(bits); #endif len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); for (i = 0, ctr = 1; i < len; i++, ctr++) { #ifdef WOLFSSL_ASYNC_CRYPT ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId); #else ret = wc_InitSha256(&sha); #endif if (ret != 0) break; if (ret == 0) ret = wc_Sha256Update(&sha, &ctr, sizeof(ctr)); if (ret == 0) ret = wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits)); if (ret == 0) { /* churning V is the only string that doesn't have the type added */ if (type != drbgInitV) ret = wc_Sha256Update(&sha, &type, sizeof(type)); } if (ret == 0) ret = wc_Sha256Update(&sha, inA, inASz); if (ret == 0) { if (inB != NULL && inBSz > 0) ret = wc_Sha256Update(&sha, inB, inBSz); } if (ret == 0) ret = wc_Sha256Final(&sha, digest); wc_Sha256Free(&sha); if (ret == 0) { if (outSz > OUTPUT_BLOCK_LEN) { XMEMCPY(out, digest, OUTPUT_BLOCK_LEN); outSz -= OUTPUT_BLOCK_LEN; out += OUTPUT_BLOCK_LEN; } else { XMEMCPY(out, digest, outSz); } } } ForceZero(digest, SHA256_DIGEST_SIZE); FREE_VAR(digest, drbg->heap); return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE; }
int wc_HmacFinal(Hmac* hmac, byte* hash) { int ret; if (hmac == NULL || hash == NULL) { return BAD_FUNC_ARG; } #ifdef WOLF_CRYPTO_CB if (hmac->devId != INVALID_DEVID) { ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash); if (ret != CRYPTOCB_UNAVAILABLE) return ret; /* fall-through when unavailable */ ret = 0; /* reset error code */ } #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { int hashLen = wc_HmacSizeByType(hmac->macType); if (hashLen <= 0) return hashLen; #if defined(HAVE_CAVIUM) return NitroxHmacFinal(hmac, hash, hashLen); #elif defined(HAVE_INTEL_QA) if (IntelQaHmacGetType(hmac->macType, NULL) == 0) { return IntelQaHmac(&hmac->asyncDev, hmac->macType, (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen); } #endif } #endif /* WOLFSSL_ASYNC_CRYPT */ if (!hmac->innerHashKeyed) { ret = HmacKeyInnerHash(hmac); if (ret != 0) return ret; } switch (hmac->macType) { #ifndef NO_MD5 case WC_MD5: ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad, WC_MD5_BLOCK_SIZE); if (ret != 0) break; ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash, WC_MD5_DIGEST_SIZE); if (ret != 0) break; ret = wc_Md5Final(&hmac->hash.md5, hash); break; #endif /* !NO_MD5 */ #ifndef NO_SHA case WC_SHA: ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad, WC_SHA_BLOCK_SIZE); if (ret != 0) break; ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash, WC_SHA_DIGEST_SIZE); if (ret != 0) break; ret = wc_ShaFinal(&hmac->hash.sha, hash); break; #endif /* !NO_SHA */ #ifdef WOLFSSL_SHA224 case WC_SHA224: { ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad, WC_SHA224_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash, WC_SHA224_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha224Final(&hmac->hash.sha224, hash); if (ret != 0) break; } break; #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 case WC_SHA256: ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad, WC_SHA256_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash, WC_SHA256_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha256Final(&hmac->hash.sha256, hash); break; #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA384 case WC_SHA384: ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad, WC_SHA384_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash, WC_SHA384_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha384Final(&hmac->hash.sha384, hash); break; #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 case WC_SHA512: ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad, WC_SHA512_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash, WC_SHA512_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha512Final(&hmac->hash.sha512, hash); break; #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*)hmac->innerHash, BLAKE2B_256); if (ret != 0) break; ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->opad, BLAKE2B_BLOCKBYTES); if (ret != 0) break; ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->innerHash, BLAKE2B_256); if (ret != 0) break; ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); break; #endif /* HAVE_BLAKE2 */ #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 case WC_SHA3_224: ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_224_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, WC_SHA3_224_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash); break; #endif #ifndef WOLFSSL_NOSHA3_256 case WC_SHA3_256: ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_256_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, WC_SHA3_256_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash); break; #endif #ifndef WOLFSSL_NOSHA3_384 case WC_SHA3_384: ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_384_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, WC_SHA3_384_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash); break; #endif #ifndef WOLFSSL_NOSHA3_512 case WC_SHA3_512: ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_512_BLOCK_SIZE); if (ret != 0) break; ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, WC_SHA3_512_DIGEST_SIZE); if (ret != 0) break; ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash); break; #endif #endif /* WOLFSSL_SHA3 */ default: ret = BAD_FUNC_ARG; break; } if (ret == 0) { hmac->innerHashKeyed = 0; } return ret; }
int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { byte* ip; byte* op; word32 i, hmac_block_size = 0; int ret = 0; void* heap = NULL; if (hmac == NULL || (key == NULL && length != 0) || !(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 || type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 || type == WC_SHA3_224 || type == WC_SHA3_256 || type == WC_SHA3_384 || type == WC_SHA3_512 || type == BLAKE2B_ID)) { return BAD_FUNC_ARG; } /* if set key has already been run then make sure and free existing */ if (hmac->macType != 0) { wc_HmacFree(hmac); } hmac->innerHashKeyed = 0; hmac->macType = (byte)type; ret = _InitHmac(hmac, type, heap); if (ret != 0) return ret; #ifdef HAVE_FIPS if (length < HMAC_FIPS_MIN_KEY) return HMAC_MIN_KEYLEN_E; #endif #ifdef WOLF_CRYPTO_CB hmac->keyRaw = key; /* use buffer directly */ hmac->keyLen = length; #endif ip = (byte*)hmac->ipad; op = (byte*)hmac->opad; switch (hmac->macType) { #ifndef NO_MD5 case WC_MD5: hmac_block_size = WC_MD5_BLOCK_SIZE; if (length <= WC_MD5_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Md5Update(&hmac->hash.md5, key, length); if (ret != 0) break; ret = wc_Md5Final(&hmac->hash.md5, ip); if (ret != 0) break; length = WC_MD5_DIGEST_SIZE; } break; #endif /* !NO_MD5 */ #ifndef NO_SHA case WC_SHA: hmac_block_size = WC_SHA_BLOCK_SIZE; if (length <= WC_SHA_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_ShaUpdate(&hmac->hash.sha, key, length); if (ret != 0) break; ret = wc_ShaFinal(&hmac->hash.sha, ip); if (ret != 0) break; length = WC_SHA_DIGEST_SIZE; } break; #endif /* !NO_SHA */ #ifdef WOLFSSL_SHA224 case WC_SHA224: { hmac_block_size = WC_SHA224_BLOCK_SIZE; if (length <= WC_SHA224_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha224Update(&hmac->hash.sha224, key, length); if (ret != 0) break; ret = wc_Sha224Final(&hmac->hash.sha224, ip); if (ret != 0) break; length = WC_SHA224_DIGEST_SIZE; } } break; #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 case WC_SHA256: hmac_block_size = WC_SHA256_BLOCK_SIZE; if (length <= WC_SHA256_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha256Update(&hmac->hash.sha256, key, length); if (ret != 0) break; ret = wc_Sha256Final(&hmac->hash.sha256, ip); if (ret != 0) break; length = WC_SHA256_DIGEST_SIZE; } break; #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA384 case WC_SHA384: hmac_block_size = WC_SHA384_BLOCK_SIZE; if (length <= WC_SHA384_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha384Update(&hmac->hash.sha384, key, length); if (ret != 0) break; ret = wc_Sha384Final(&hmac->hash.sha384, ip); if (ret != 0) break; length = WC_SHA384_DIGEST_SIZE; } break; #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 case WC_SHA512: hmac_block_size = WC_SHA512_BLOCK_SIZE; if (length <= WC_SHA512_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha512Update(&hmac->hash.sha512, key, length); if (ret != 0) break; ret = wc_Sha512Final(&hmac->hash.sha512, ip); if (ret != 0) break; length = WC_SHA512_DIGEST_SIZE; } break; #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_BLAKE2 case BLAKE2B_ID: hmac_block_size = BLAKE2B_BLOCKBYTES; if (length <= BLAKE2B_BLOCKBYTES) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length); if (ret != 0) break; ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); if (ret != 0) break; length = BLAKE2B_256; } break; #endif /* HAVE_BLAKE2 */ #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 case WC_SHA3_224: hmac_block_size = WC_SHA3_224_BLOCK_SIZE; if (length <= WC_SHA3_224_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length); if (ret != 0) break; ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip); if (ret != 0) break; length = WC_SHA3_224_DIGEST_SIZE; } break; #endif #ifndef WOLFSSL_NOSHA3_256 case WC_SHA3_256: hmac_block_size = WC_SHA3_256_BLOCK_SIZE; if (length <= WC_SHA3_256_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length); if (ret != 0) break; ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip); if (ret != 0) break; length = WC_SHA3_256_DIGEST_SIZE; } break; #endif #ifndef WOLFSSL_NOSHA3_384 case WC_SHA3_384: hmac_block_size = WC_SHA3_384_BLOCK_SIZE; if (length <= WC_SHA3_384_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length); if (ret != 0) break; ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip); if (ret != 0) break; length = WC_SHA3_384_DIGEST_SIZE; } break; #endif #ifndef WOLFSSL_NOSHA3_512 case WC_SHA3_512: hmac_block_size = WC_SHA3_512_BLOCK_SIZE; if (length <= WC_SHA3_512_BLOCK_SIZE) { if (key != NULL) { XMEMCPY(ip, key, length); } } else { ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length); if (ret != 0) break; ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip); if (ret != 0) break; length = WC_SHA3_512_DIGEST_SIZE; } break; #endif #endif /* WOLFSSL_SHA3 */ default: return BAD_FUNC_ARG; } #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM) #ifdef HAVE_INTEL_QA if (IntelQaHmacGetType(hmac->macType, NULL) == 0) #endif { if (length > hmac_block_size) length = hmac_block_size; /* update key length */ hmac->keyLen = (word16)length; return ret; } /* no need to pad below */ #endif } #endif if (ret == 0) { if (length < hmac_block_size) XMEMSET(ip + length, 0, hmac_block_size - length); for(i = 0; i < hmac_block_size; i++) { op[i] = ip[i] ^ OPAD; ip[i] ^= IPAD; } } return ret; }