static SigV4Status_t generateSigningKey()

in source/sigv4.c [2972:3070]


static SigV4Status_t generateSigningKey( const SigV4Parameters_t * pSigV4Params,
                                         HmacContext_t * pHmacContext,
                                         SigV4String_t * pSigningKey,
                                         size_t * pBytesRemaining )
{
    SigV4Status_t returnStatus = SigV4Success;
    int32_t hmacStatus = 0;
    char * pSigningKeyStart = NULL;

    assert( pSigV4Params != NULL );
    assert( pHmacContext != NULL );
    assert( pSigningKey != NULL );
    assert( pBytesRemaining != NULL );

    /* To calculate the final signing key, this function needs at least enough
     * buffer to hold the length of two digests since one digest is used to
     * calculate the other. */
    if( *pBytesRemaining < ( pSigV4Params->pCryptoInterface->hashDigestLen * 2U ) )
    {
        returnStatus = SigV4InsufficientMemory;
        LOG_INSUFFICIENT_MEMORY_ERROR( "generate signing key",
                                       ( pSigV4Params->pCryptoInterface->hashDigestLen * 2U ) - *pBytesRemaining );
    }

    if( returnStatus != SigV4InsufficientMemory )
    {
        /* Fill the key prefix, "AWS4" in the HMAC context cache.
         * The prefix is part of the key for the first round of HMAC operation:
         * HMAC("AWS4" + SecretKey, Date) */
        hmacStatus = hmacAddKey( pHmacContext,
                                 SIGV4_HMAC_SIGNING_KEY_PREFIX,
                                 SIGV4_HMAC_SIGNING_KEY_PREFIX_LEN,
                                 true /* Is key prefix. */ );

        /* The above call should always succeed as it only populates the HMAC key cache. */
        assert( hmacStatus == 0 );
    }

    if( ( returnStatus != SigV4InsufficientMemory ) && ( hmacStatus == 0 ) )
    {
        hmacStatus = completeHmac( pHmacContext,
                                   pSigV4Params->pCredentials->pSecretAccessKey,
                                   pSigV4Params->pCredentials->secretAccessKeyLen,
                                   pSigV4Params->pDateIso8601,
                                   ISO_DATE_SCOPE_LEN,
                                   pSigningKey->pData,
                                   pSigningKey->dataLen );
        *pBytesRemaining -= pSigV4Params->pCryptoInterface->hashDigestLen;
    }

    if( ( returnStatus != SigV4InsufficientMemory ) && ( hmacStatus == 0 ) )
    {
        pSigningKeyStart = pSigningKey->pData + pSigV4Params->pCryptoInterface->hashDigestLen + 1U;
        hmacStatus = completeHmac( pHmacContext,
                                   pSigningKey->pData,
                                   pSigV4Params->pCryptoInterface->hashDigestLen,
                                   pSigV4Params->pRegion,
                                   pSigV4Params->regionLen,
                                   pSigningKeyStart,
                                   *pBytesRemaining );
        *pBytesRemaining -= pSigV4Params->pCryptoInterface->hashDigestLen;
    }

    if( ( returnStatus != SigV4InsufficientMemory ) && ( hmacStatus == 0 ) )
    {
        hmacStatus = completeHmac( pHmacContext,
                                   pSigningKeyStart,
                                   pSigV4Params->pCryptoInterface->hashDigestLen,
                                   pSigV4Params->pService,
                                   pSigV4Params->serviceLen,
                                   pSigningKey->pData,
                                   pSigV4Params->pCryptoInterface->hashDigestLen );
    }

    if( ( returnStatus != SigV4InsufficientMemory ) && ( hmacStatus == 0 ) )
    {
        hmacStatus = completeHmac( pHmacContext,
                                   pSigningKey->pData,
                                   pSigV4Params->pCryptoInterface->hashDigestLen,
                                   CREDENTIAL_SCOPE_TERMINATOR,
                                   CREDENTIAL_SCOPE_TERMINATOR_LEN,
                                   pSigningKeyStart,
                                   pSigV4Params->pCryptoInterface->hashDigestLen );
    }

    if( ( returnStatus != SigV4InsufficientMemory ) && ( hmacStatus == 0 ) )
    {
        pSigningKey->pData = pSigningKeyStart;
        pSigningKey->dataLen = pSigV4Params->pCryptoInterface->hashDigestLen;
    }

    /* If there was a hashing error in HMAC operations, set the appropriate error code. */
    if( hmacStatus != 0 )
    {
        returnStatus = SigV4HashError;
    }

    return returnStatus;
}