static int32_t hmacAddKey()

in source/sigv4.c [2332:2401]


static int32_t hmacAddKey( HmacContext_t * pHmacContext,
                           const char * pKey,
                           size_t keyLen,
                           bool isKeyPrefix )
{
    int32_t returnStatus = 0;
    const SigV4CryptoInterface_t * pCryptoInterface = NULL;
    const uint8_t * pUnsignedKey = ( const uint8_t * ) pKey;

    assert( pHmacContext != NULL );
    assert( pHmacContext->key != NULL );
    assert( pHmacContext->pCryptoInterface != NULL );
    assert( pHmacContext->pCryptoInterface->hashInit != NULL );
    assert( pHmacContext->pCryptoInterface->hashUpdate != NULL );
    assert( pHmacContext->pCryptoInterface->hashFinal != NULL );

    pCryptoInterface = pHmacContext->pCryptoInterface;

    /* At the first time this function is called, it is important that pHmacContext->keyLen
     * is set to 0U so that the key can be copied to the start of the buffer. */
    if( ( pHmacContext->keyLen + keyLen ) <= pCryptoInterface->hashBlockLen )
    {
        /* The key fits into the block so just append it. */
        ( void ) memcpy( &pHmacContext->key[ pHmacContext->keyLen ], pUnsignedKey, keyLen );
        pHmacContext->keyLen += keyLen;
    }
    else
    {
        returnStatus = pCryptoInterface->hashInit( pCryptoInterface->pHashContext );

        /* Hash part of the key that is cached in the HMAC context. */
        if( returnStatus == 0 )
        {
            returnStatus = pCryptoInterface->hashUpdate( pCryptoInterface->pHashContext,
                                                         pHmacContext->key,
                                                         pHmacContext->keyLen );
        }

        /* Hash down the remaining part of the key in order to create a block-sized derived key. */
        if( returnStatus == 0 )
        {
            returnStatus = pCryptoInterface->hashUpdate( pCryptoInterface->pHashContext,
                                                         pUnsignedKey,
                                                         keyLen );
        }

        if( returnStatus == 0 )
        {
            /* Store the final block-sized derived key. */
            returnStatus = pCryptoInterface->hashFinal( pCryptoInterface->pHashContext,
                                                        pHmacContext->key,
                                                        pCryptoInterface->hashBlockLen );
            pHmacContext->keyLen = pCryptoInterface->hashDigestLen;
        }
    }

    /* If the complete key has been obtained and it is less than the hash block size, then append
     * padding with zero valued bytes to make it block-sized. */
    if( !isKeyPrefix && ( returnStatus == 0 ) && ( pHmacContext->keyLen < pCryptoInterface->hashBlockLen ) )
    {
        /* Zero pad to the right so that the key has the same size as the block size. */
        ( void ) memset( ( void * ) ( &pHmacContext->key[ pHmacContext->keyLen ] ),
                         0,
                         pCryptoInterface->hashBlockLen - pHmacContext->keyLen );

        pHmacContext->keyLen = pCryptoInterface->hashBlockLen;
    }

    return returnStatus;
}