int avs_crypto_aead_aes_ccm_decrypt(const unsigned char *key, size_t key_len, const unsigned char *iv, size_t iv_len, const unsigned char *aad, size_t aad_len, const unsigned char *input, size_t input_len, const unsigned char *tag, size_t tag_len, unsigned char *output) { assert(key); assert(iv); assert(!aad_len || aad); assert(!input_len || input); assert(tag); assert(!input_len || output); if (!_avs_crypto_aead_parameters_valid(key_len, iv_len, tag_len)) { return -1; } mbedtls_ccm_context ccm_ctx; mbedtls_ccm_init(&ccm_ctx); int result; (void) ((result = mbedtls_ccm_setkey(&ccm_ctx, MBEDTLS_CIPHER_ID_AES, key, (unsigned int) key_len * 8U)) || (result = mbedtls_ccm_auth_decrypt(&ccm_ctx, input_len, iv, iv_len, aad, aad_len, input, output, tag, tag_len))); mbedtls_ccm_free(&ccm_ctx); if (result) { LOG(ERROR, "mbed TLS error %d", result); return -1; } return 0; }
bool AES_CCM_Decrypt(COSE_Enveloped * pcose, int TSize, int LSize, const byte * pbKey, size_t cbKey, const byte * pbCrypto, size_t cbCrypto, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr) { mbedtls_ccm_context ctx; int cbOut; byte * rgbOut = NULL; int NSize = 15 - (LSize/8); byte rgbIV[15] = { 0 }; const cn_cbor * pIV = NULL; mbedtls_cipher_id_t cipher; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pcose->m_message.m_allocContext; #endif mbedtls_ccm_init(&ctx); // Setup the IV/Nonce and put it into the message pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL); if ((pIV == NULL) || (pIV->type!= CN_CBOR_BYTES)) { if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER; errorReturn: if (rgbOut != NULL) COSE_FREE(rgbOut, context); mbedtls_ccm_free(&ctx); return false; } CHECK_CONDITION(pIV->length == NSize, COSE_ERR_INVALID_PARAMETER); memcpy(rgbIV, pIV->v.str, pIV->length); // Setup and run the mbedTLS code cipher = MBEDTLS_CIPHER_ID_AES; CHECK_CONDITION(!mbedtls_ccm_setkey(&ctx, cipher, pbKey, cbKey*8), COSE_ERR_CRYPTO_FAIL); TSize /= 8; // Comes in in bits not bytes. cbOut = (int) cbCrypto - TSize; rgbOut = (byte *)COSE_CALLOC(cbOut, 1, context); CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(!mbedtls_ccm_auth_decrypt(&ctx, cbOut, rgbIV, NSize, pbAuthData, cbAuthData, pbCrypto, rgbOut, &pbCrypto[cbOut], TSize), COSE_ERR_CRYPTO_FAIL); mbedtls_ccm_free(&ctx); pcose->pbContent = rgbOut; pcose->cbContent = cbOut; return true; }
/* * Packet-oriented decryption for AEAD modes */ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, const unsigned char *tag, size_t tag_len ) { #if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { int ret; *olen = ilen; ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, iv, iv_len, ad, ad_len, tag, tag_len, input, output ); if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; return( ret ); } #endif /* MBEDTLS_GCM_C */ #if defined(MBEDTLS_CCM_C) if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) { int ret; *olen = ilen; ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, iv, iv_len, ad, ad_len, input, output, tag, tag_len ); if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; return( ret ); } #endif /* MBEDTLS_CCM_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); }
/* * Packet-oriented decryption for AEAD modes */ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, const unsigned char *tag, size_t tag_len ) { #if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { int ret; *olen = ilen; ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, iv, iv_len, ad, ad_len, tag, tag_len, input, output ); if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; return( ret ); } #endif /* MBEDTLS_GCM_C */ #if defined(MBEDTLS_CCM_C) if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) { int ret; *olen = ilen; ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, iv, iv_len, ad, ad_len, input, output, tag, tag_len ); if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; return( ret ); } #endif /* MBEDTLS_CCM_C */ #if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { int ret; /* ChachaPoly has fixed length nonce and MAC (tag) */ if ( ( iv_len != ctx->cipher_info->iv_size ) || ( tag_len != 16U ) ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } *olen = ilen; ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, iv, ad, ad_len, tag, input, output ); if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; return( ret ); } #endif /* MBEDTLS_CHACHAPOLY_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); }