Exemple #1
0
int wc_Sha224Hash(const byte* data, word32 len, byte* hash)
{
    int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
    Sha224* sha224;
#else
    Sha224 sha224[1];
#endif

#ifdef WOLFSSL_SMALL_STACK
    sha224 = (Sha224*)XMALLOC(sizeof(Sha224), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (sha224 == NULL)
        return MEMORY_E;
#endif

    if ((ret = wc_InitSha224(sha224)) != 0) {
        WOLFSSL_MSG("InitSha224 failed");
    }
    else if ((ret = wc_Sha224Update(sha224, data, len)) != 0) {
        WOLFSSL_MSG("Sha224Update failed");
    }
    else if ((ret = wc_Sha224Final(sha224, hash)) != 0) {
        WOLFSSL_MSG("Sha224Final failed");
    }

#ifdef WOLFSSL_SMALL_STACK
    XFREE(sha224, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    return ret;
}
Exemple #2
0
int wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type, byte* out)
{
    int ret = HASH_TYPE_E; /* Default to hash type error */

    if (hash == NULL || out == NULL)
        return BAD_FUNC_ARG;

    switch (type) {
        case WC_HASH_TYPE_MD5:
#ifndef NO_MD5
            wc_Md5Final(&hash->md5, out);
#endif
            break;
        case WC_HASH_TYPE_SHA:
#ifndef NO_SHA
            ret = wc_ShaFinal(&hash->sha, out);
            if (ret != 0)
                return ret;
#endif
            break;
        case WC_HASH_TYPE_SHA224:
#ifdef WOLFSSL_SHA224
            ret = wc_Sha224Final(&hash->sha224, out);
            if (ret != 0)
                return ret;
#endif
            break;
        case WC_HASH_TYPE_SHA256:
#ifndef NO_SHA256
            ret = wc_Sha256Final(&hash->sha256, out);
            if (ret != 0)
                return ret;
#endif
            break;
        case WC_HASH_TYPE_SHA384:
#ifdef WOLFSSL_SHA384
            ret = wc_Sha384Final(&hash->sha384, out);
            if (ret != 0)
                return ret;
#endif
            break;
        case WC_HASH_TYPE_SHA512:
#ifdef WOLFSSL_SHA512
            ret = wc_Sha512Final(&hash->sha512, out);
            if (ret != 0)
                return ret;
#endif
            break;

        /* not supported */
        case WC_HASH_TYPE_MD5_SHA:
        case WC_HASH_TYPE_MD2:
        case WC_HASH_TYPE_MD4:
        case WC_HASH_TYPE_NONE:
        default:
            return BAD_FUNC_ARG;
    };

    return 0;
}
Exemple #3
0
int wc_Sha224GetHash(Sha224* sha224, byte* hash)
{
    int ret;
    Sha224 save;

    if (sha224 == NULL || hash == NULL)
        return BAD_FUNC_ARG;

    save= *sha224;
    ret = wc_Sha224Final(sha224, hash);
    *sha224 = save;

    return ret;
}
Exemple #4
0
int sha224_test(void)
{
    Sha224 sha;
    byte   hash[SHA224_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 = "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55"
               "\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7";
    a.inLen  = XSTRLEN(a.input);
    a.outLen = SHA224_DIGEST_SIZE;

    b.input  = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
    b.output = "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01"
               "\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25";
    b.inLen  = XSTRLEN(b.input);
    b.outLen = SHA224_DIGEST_SIZE;

    test_sha[0] = a;
    test_sha[1] = b;

    ret = wc_InitSha224(&sha);
    if (ret != 0)
        return -4005;

    for (i = 0; i < times; ++i) {
        ret = wc_Sha224Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen);
        if (ret != 0)
            return ret;
        ret = wc_Sha224Final(&sha, hash);
        if (ret != 0)
            return ret;

        if (XMEMCMP(hash, test_sha[i].output, SHA224_DIGEST_SIZE) != 0)
            return -10 - i;
    }

    return 0;
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
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;
}
Exemple #8
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;
}