/** * In order to decrypt keys as VMK or FVEK, use this function * * @param input The AES encrypted buffer to decrypt * @param key The key to decrypt the input buffer (already extracted from a datum_key_t structure) * @param output The decrypted result * @param output_size The size of the decrypted result * @return TRUE if result can be trusted, FALSE otherwise */ int decrypt_key( unsigned char* input, unsigned int input_size, unsigned char* mac, unsigned char* nonce, unsigned char* key, unsigned int keybits, void** output) { // Check parameters if(!input || !mac || !nonce || !key || !output) return FALSE; AES_CONTEXT ctx; uint8_t mac_first [AUTHENTICATOR_LENGTH]; uint8_t mac_second[AUTHENTICATOR_LENGTH]; /* * Allocate output buffer */ *output = dis_malloc(input_size); memset(*output, 0, input_size); /* * Get the MAC */ memcpy(mac_first, mac, AUTHENTICATOR_LENGTH); /* * Set key which is used to decrypt (already extracted from a datum_key_t structure) */ AES_SETENC_KEY(&ctx, key, keybits); /* * Decrypt the input buffer now * NOTE: The 0xc is the nonce length (hardcoded) */ dis_printf(L_DEBUG, "}--------[ Data passed to aes_ccm_encrypt_decrypt ]--------{\n"); dis_printf(L_DEBUG, "-- Nonce:\n"); hexdump(L_DEBUG, nonce, 0xc); dis_printf(L_DEBUG, "-- Input buffer:\n"); hexdump(L_DEBUG, input, input_size); dis_printf(L_DEBUG, "-- MAC:\n"); hexdump(L_DEBUG, mac_first, AUTHENTICATOR_LENGTH); dis_printf(L_DEBUG, "}----------------------------------------------------------{\n"); aes_ccm_encrypt_decrypt( &ctx, nonce, 0xc, input, input_size, mac_first, AUTHENTICATOR_LENGTH, (unsigned char*) *output ); /* * Compute to check decryption */ memset(mac_second, 0, AUTHENTICATOR_LENGTH); aes_ccm_compute_unencrypted_tag( &ctx, nonce, 0xc, (unsigned char*) *output, input_size, mac_second ); memset(&ctx, 0, sizeof(AES_CONTEXT)); /* * Check if the MACs correspond, if not, * we didn't decrypt correctly the input buffer */ dis_printf(L_DEBUG, "Looking if MACs match...\n"); dis_printf(L_DEBUG, "They are just below:\n"); hexdump(L_DEBUG, mac_first, AUTHENTICATOR_LENGTH); hexdump(L_DEBUG, mac_second, AUTHENTICATOR_LENGTH); if(memcmp(mac_first, mac_second, AUTHENTICATOR_LENGTH) != 0) { dis_printf(L_ERROR, "The MACs don't match.\n"); return FALSE; } dis_printf(L_DEBUG, "Ok, they match!\n"); memset(mac_first, 0, AUTHENTICATOR_LENGTH); memset(mac_second, 0, AUTHENTICATOR_LENGTH); return TRUE; }
/** * In order to decrypt keys as VMK or FVEK, use this function * * @param input The AES encrypted buffer to decrypt * @param key The key to decrypt the input buffer (already extracted from a datum_key_t structure) * @param output The decrypted result * @param output_size The size of the decrypted result * @return TRUE if result can be trusted, FALSE otherwise */ int decrypt_key(datum_aes_ccm_t* input, unsigned char* key, void** output, unsigned int* output_size) { // Check parameters if(!input || !key || !output || !output_size) return FALSE; AES_CONTEXT ctx; unsigned int header_size = 0; unsigned char* aes_input_buffer = NULL; unsigned int input_size = 0; uint8_t mac_first [AUTHENTICATOR_LENGTH]; uint8_t mac_second[AUTHENTICATOR_LENGTH]; header_size = datum_types_prop[input->header.datum_type].size_header; *output_size = input->header.datum_size - header_size; input_size = *output_size; /* * Allocate output buffer */ *output = xmalloc(*output_size); memset(*output, 0, *output_size); /* * The aes input buffer is data to decrypt */ aes_input_buffer = xmalloc(*output_size); memcpy(aes_input_buffer, (unsigned char*)input + header_size, *output_size); /* * Get the MAC */ memcpy(mac_first, input->mac, AUTHENTICATOR_LENGTH); /* * Set key which is used to decrypt (already extracted from a datum_key_t structure) */ AES_SETENC_KEY(&ctx, key, AES_CTX_LENGTH); /* * Decrypt the input buffer now * NOTE: The 0xc is the nonce length (hardcoded) */ xprintf(L_DEBUG, "}--------[ Data passed to aes_ccm_encrypt_decrypt ]--------{\n"); xprintf(L_DEBUG, "-- Nonce:\n"); hexdump(L_DEBUG, input->nonce, 0xc); xprintf(L_DEBUG, "-- Input buffer:\n"); hexdump(L_DEBUG, aes_input_buffer, input_size); xprintf(L_DEBUG, "-- MAC:\n"); hexdump(L_DEBUG, mac_first, AUTHENTICATOR_LENGTH); xprintf(L_DEBUG, "}----------------------------------------------------------{\n"); aes_ccm_encrypt_decrypt(&ctx, input->nonce, 0xc, aes_input_buffer, input_size, mac_first, AUTHENTICATOR_LENGTH, (unsigned char*) *output); xfree(aes_input_buffer); /* * Compute to check decryption */ memset(mac_second, 0, AUTHENTICATOR_LENGTH); aes_ccm_compute_unencrypted_tag(&ctx, input->nonce, 0xc, (unsigned char*) *output, *output_size, mac_second); memset(&ctx, 0, sizeof(AES_CONTEXT)); /* * Check if the MACs correspond, if not, * we didn't decrypt correctly the input buffer */ xprintf(L_INFO, "Looking if MACs match...\n"); xprintf(L_DEBUG, "They are just below:\n"); hexdump(L_DEBUG, mac_first, AUTHENTICATOR_LENGTH); hexdump(L_DEBUG, mac_second, AUTHENTICATOR_LENGTH); if(memcmp(mac_first, mac_second, AUTHENTICATOR_LENGTH) != 0) { xprintf(L_ERROR, "The MACs don't match.\n"); return FALSE; } xprintf(L_INFO, "Ok, they match!\n"); memset(mac_first, 0, AUTHENTICATOR_LENGTH); memset(mac_second, 0, AUTHENTICATOR_LENGTH); return TRUE; }