| 670 | } |
| 671 | |
| 672 | Reference<EncryptBuf> DecryptBlobCipherAes256Ctr::decrypt(const uint8_t* ciphertext, |
| 673 | const int ciphertextLen, |
| 674 | const BlobCipherEncryptHeader& header, |
| 675 | Arena& arena) { |
| 676 | CODE_PROBE(true, "Decrypting data with BlobCipher"); |
| 677 | |
| 678 | verifyEncryptHeaderMetadata(header); |
| 679 | |
| 680 | if (header.flags.authTokenMode != ENCRYPT_HEADER_AUTH_TOKEN_MODE_NONE && !headerCipherKey.isValid()) { |
| 681 | TraceEvent("Decrypt_InvalidHeaderCipherKey").detail("AuthTokenMode", header.flags.authTokenMode); |
| 682 | throw encrypt_ops_error(); |
| 683 | } |
| 684 | |
| 685 | const int allocSize = header.flags.authTokenMode == ENCRYPT_HEADER_AUTH_TOKEN_MODE_SINGLE |
| 686 | ? ciphertextLen + AES_BLOCK_SIZE + sizeof(BlobCipherEncryptHeader) |
| 687 | : ciphertextLen + AES_BLOCK_SIZE; |
| 688 | Reference<EncryptBuf> decrypted = makeReference<EncryptBuf>(allocSize, arena); |
| 689 | |
| 690 | if (header.flags.authTokenMode != ENCRYPT_HEADER_AUTH_TOKEN_MODE_NONE) { |
| 691 | verifyAuthTokens(ciphertext, ciphertextLen, header, decrypted->begin(), arena); |
| 692 | ASSERT(authTokensValidationDone); |
| 693 | } |
| 694 | |
| 695 | uint8_t* plaintext = decrypted->begin(); |
| 696 | int bytesDecrypted{ 0 }; |
| 697 | if (!EVP_DecryptUpdate(ctx, plaintext, &bytesDecrypted, ciphertext, ciphertextLen)) { |
| 698 | TraceEvent("Decrypt_UpdateFailed") |
| 699 | .detail("BaseCipherId", header.cipherTextDetails.baseCipherId) |
| 700 | .detail("EncryptDomainId", header.cipherTextDetails.encryptDomainId); |
| 701 | throw encrypt_ops_error(); |
| 702 | } |
| 703 | |
| 704 | int finalBlobBytes{ 0 }; |
| 705 | if (EVP_DecryptFinal_ex(ctx, plaintext + bytesDecrypted, &finalBlobBytes) <= 0) { |
| 706 | TraceEvent("Decrypt_FinalFailed") |
| 707 | .detail("BaseCipherId", header.cipherTextDetails.baseCipherId) |
| 708 | .detail("EncryptDomainId", header.cipherTextDetails.encryptDomainId); |
| 709 | throw encrypt_ops_error(); |
| 710 | } |
| 711 | |
| 712 | if ((bytesDecrypted + finalBlobBytes) != ciphertextLen) { |
| 713 | TraceEvent("Encrypt_UnexpectedPlaintextLen") |
| 714 | .detail("CiphertextLen", ciphertextLen) |
| 715 | .detail("DecryptedBufLen", bytesDecrypted + finalBlobBytes); |
| 716 | throw encrypt_ops_error(); |
| 717 | } |
| 718 | |
| 719 | decrypted->setLogicalSize(ciphertextLen); |
| 720 | return decrypted; |
| 721 | } |
| 722 | |
| 723 | DecryptBlobCipherAes256Ctr::~DecryptBlobCipherAes256Ctr() { |
| 724 | if (ctx != nullptr) { |
no test coverage detected