ocb_utils.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright 2015 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <keymaster/key_blob_utils/ocb_utils.h>
  17. #include <assert.h>
  18. #include <openssl/aes.h>
  19. #include <openssl/sha.h>
  20. #include <hardware/keymaster_defs.h>
  21. #include <keymaster/authorization_set.h>
  22. #include <keymaster/android_keymaster_utils.h>
  23. #include <keymaster/km_openssl/openssl_err.h>
  24. #include <keymaster/new>
  25. namespace keymaster {
  26. class AeCtx {
  27. public:
  28. AeCtx() : ctx_(ae_allocate(nullptr)) {}
  29. ~AeCtx() {
  30. ae_clear(ctx_);
  31. ae_free(ctx_);
  32. }
  33. ae_ctx* get() { return ctx_; }
  34. private:
  35. ae_ctx* ctx_;
  36. };
  37. static keymaster_error_t BuildDerivationData(const AuthorizationSet& hw_enforced,
  38. const AuthorizationSet& sw_enforced,
  39. const AuthorizationSet& hidden,
  40. UniquePtr<uint8_t[]>* derivation_data,
  41. size_t* derivation_data_length) {
  42. *derivation_data_length =
  43. hidden.SerializedSize() + hw_enforced.SerializedSize() + sw_enforced.SerializedSize();
  44. derivation_data->reset(new (std::nothrow) uint8_t[*derivation_data_length]);
  45. if (!derivation_data->get())
  46. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  47. uint8_t* buf = derivation_data->get();
  48. uint8_t* end = derivation_data->get() + *derivation_data_length;
  49. buf = hidden.Serialize(buf, end);
  50. buf = hw_enforced.Serialize(buf, end);
  51. buf = sw_enforced.Serialize(buf, end);
  52. return KM_ERROR_OK;
  53. }
  54. static keymaster_error_t InitializeKeyWrappingContext(const AuthorizationSet& hw_enforced,
  55. const AuthorizationSet& sw_enforced,
  56. const AuthorizationSet& hidden,
  57. const KeymasterKeyBlob& master_key,
  58. AeCtx* ctx) {
  59. size_t derivation_data_length;
  60. UniquePtr<uint8_t[]> derivation_data;
  61. keymaster_error_t error = BuildDerivationData(hw_enforced, sw_enforced, hidden,
  62. &derivation_data, &derivation_data_length);
  63. if (error != KM_ERROR_OK)
  64. return error;
  65. SHA256_CTX sha256_ctx;
  66. UniquePtr<uint8_t[]> hash_buf(new (std::nothrow) uint8_t[SHA256_DIGEST_LENGTH]);
  67. if (!hash_buf.get())
  68. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  69. Eraser hash_eraser(hash_buf.get(), SHA256_DIGEST_LENGTH);
  70. UniquePtr<uint8_t[]> derived_key(new (std::nothrow) uint8_t[AES_BLOCK_SIZE]);
  71. if (!derived_key.get())
  72. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  73. Eraser derived_key_eraser(derived_key.get(), AES_BLOCK_SIZE);
  74. if (!ctx->get() || !hash_buf.get() || !derived_key.get())
  75. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  76. // Hash derivation data.
  77. Eraser sha256_ctx_eraser(sha256_ctx);
  78. SHA256_Init(&sha256_ctx);
  79. SHA256_Update(&sha256_ctx, derivation_data.get(), derivation_data_length);
  80. SHA256_Final(hash_buf.get(), &sha256_ctx);
  81. // Encrypt hash with master key to build derived key.
  82. AES_KEY aes_key;
  83. Eraser aes_key_eraser(AES_KEY);
  84. if (0 !=
  85. AES_set_encrypt_key(master_key.key_material, master_key.key_material_size * 8, &aes_key))
  86. return TranslateLastOpenSslError();
  87. AES_encrypt(hash_buf.get(), derived_key.get(), &aes_key);
  88. // Set up AES OCB context using derived key.
  89. if (ae_init(ctx->get(), derived_key.get(), AES_BLOCK_SIZE /* key length */, OCB_NONCE_LENGTH,
  90. OCB_TAG_LENGTH) != AE_SUCCESS) {
  91. memset_s(ctx->get(), 0, ae_ctx_sizeof());
  92. return KM_ERROR_UNKNOWN_ERROR;
  93. }
  94. return KM_ERROR_OK;
  95. }
  96. keymaster_error_t OcbEncryptKey(const AuthorizationSet& hw_enforced,
  97. const AuthorizationSet& sw_enforced, const AuthorizationSet& hidden,
  98. const KeymasterKeyBlob& master_key,
  99. const KeymasterKeyBlob& plaintext, const Buffer& nonce,
  100. KeymasterKeyBlob* ciphertext, Buffer* tag) {
  101. assert(ciphertext && tag);
  102. if (nonce.available_read() != OCB_NONCE_LENGTH)
  103. return KM_ERROR_INVALID_ARGUMENT;
  104. AeCtx ctx;
  105. if (!ctx.get())
  106. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  107. keymaster_error_t error =
  108. InitializeKeyWrappingContext(hw_enforced, sw_enforced, hidden, master_key, &ctx);
  109. if (error != KM_ERROR_OK)
  110. return error;
  111. if (!ciphertext->Reset(plaintext.key_material_size))
  112. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  113. int ae_err = ae_encrypt(ctx.get(), nonce.peek_read(), plaintext.key_material,
  114. plaintext.key_material_size, nullptr /* additional data */,
  115. 0 /* additional data length */, ciphertext->writable_data(),
  116. tag->peek_write(), 1 /* final */);
  117. if (ae_err < 0) {
  118. LOG_E("Error %d while encrypting key", ae_err);
  119. return KM_ERROR_UNKNOWN_ERROR;
  120. }
  121. if (!tag->advance_write(OCB_TAG_LENGTH))
  122. return KM_ERROR_UNKNOWN_ERROR;
  123. assert(ae_err == static_cast<int>(plaintext.key_material_size));
  124. return KM_ERROR_OK;
  125. }
  126. keymaster_error_t OcbDecryptKey(const AuthorizationSet& hw_enforced,
  127. const AuthorizationSet& sw_enforced, const AuthorizationSet& hidden,
  128. const KeymasterKeyBlob& master_key,
  129. const KeymasterKeyBlob& ciphertext, const Buffer& nonce,
  130. const Buffer& tag, KeymasterKeyBlob* plaintext) {
  131. assert(plaintext);
  132. if (nonce.available_read() != OCB_NONCE_LENGTH || tag.available_read() != OCB_TAG_LENGTH)
  133. return KM_ERROR_INVALID_ARGUMENT;
  134. AeCtx ctx;
  135. if (!ctx.get())
  136. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  137. keymaster_error_t error =
  138. InitializeKeyWrappingContext(hw_enforced, sw_enforced, hidden, master_key, &ctx);
  139. if (error != KM_ERROR_OK)
  140. return error;
  141. if (!plaintext->Reset(ciphertext.key_material_size))
  142. return KM_ERROR_MEMORY_ALLOCATION_FAILED;
  143. int ae_err = ae_decrypt(ctx.get(), nonce.peek_read(), ciphertext.key_material,
  144. ciphertext.key_material_size, nullptr /* additional data */,
  145. 0 /* additional data length */, plaintext->writable_data(),
  146. tag.peek_read(), 1 /* final */);
  147. if (ae_err == AE_INVALID) {
  148. // Authentication failed! Decryption probably succeeded(ish), but we don't want to return
  149. // any data when the authentication fails, so clear it.
  150. plaintext->Clear();
  151. LOG_E("Failed to validate authentication tag during key decryption", 0);
  152. return KM_ERROR_INVALID_KEY_BLOB;
  153. } else if (ae_err < 0) {
  154. LOG_E("Failed to decrypt key, error: %d", ae_err);
  155. return KM_ERROR_UNKNOWN_ERROR;
  156. }
  157. assert(ae_err == static_cast<int>(ciphertext.key_material_size));
  158. return KM_ERROR_OK;
  159. }
  160. } // namespace keymaster