Esempio n. 1
0
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;
}
Esempio n. 2
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
/* 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 */
}
Esempio n. 5
0
/* 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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
/* 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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
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;
}
Esempio n. 13
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;
}
Esempio n. 14
0
/* 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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}