system/bt
Révision | 0b7ab26948a50f6d6057d6299f27e8fc077e3f69 (tree) |
---|---|
l'heure | 2019-12-19 18:44:04 |
Auteur | weichinweng <weichinweng@goog...> |
Commiter | weichinweng |
DO NOT MERGE: NIAP: Use AES-GCM 256 bits to encrypt key.
use AES-GCM 256 bits to encrypt key.
Bug: 140483038
Test: NA
Change-Id: Ie5e85edf4fd8dbd9120ea383fd3b9214b6026816
@@ -70,9 +70,7 @@ class BtifKeystore { | ||
70 | 70 | private: |
71 | 71 | std::unique_ptr<keystore::KeystoreClient> keystore_client_; |
72 | 72 | std::mutex api_mutex_; |
73 | - keystore::KeyStoreNativeReturnCode GenerateKey(const std::string& name, | |
74 | - int32_t flags, | |
75 | - bool auth_bound); | |
73 | + bool GenerateKey(const std::string& name, int32_t flags); | |
76 | 74 | }; |
77 | 75 | |
78 | 76 | } // namespace bluetooth |
@@ -435,6 +435,7 @@ bool btif_config_get_bin(const std::string& section, const std::string& key, | ||
435 | 435 | btif_is_key_encrypted(value_str_from_config->size(), key); |
436 | 436 | |
437 | 437 | if (in_encrypt_key_name_list && is_key_encrypted) { |
438 | + VLOG(2) << __func__ << " decrypt section: " << section << " key:" << key; | |
438 | 439 | std::string tmp_value_str = |
439 | 440 | btif_convert_to_unencrypt_key(*value_str_from_config); |
440 | 441 | value_str = &tmp_value_str; |
@@ -461,6 +462,7 @@ bool btif_config_get_bin(const std::string& section, const std::string& key, | ||
461 | 462 | |
462 | 463 | if (btif_is_niap_mode()) { |
463 | 464 | if (in_encrypt_key_name_list && !is_key_encrypted) { |
465 | + VLOG(2) << __func__ << " encrypt section: " << section << " key:" << key; | |
464 | 466 | std::string encrypt_str = |
465 | 467 | btif_convert_to_encrypt_key(*value_str_from_config); |
466 | 468 | config_set_string(config.get(), section, key, encrypt_str); |
@@ -555,6 +557,7 @@ bool btif_config_set_bin(const std::string& section, const std::string& key, | ||
555 | 557 | |
556 | 558 | std::string value_str; |
557 | 559 | if (btif_is_niap_mode() && btif_in_encrypt_key_name_list(key)) { |
560 | + VLOG(2) << __func__ << " encrypt section: " << section << " key:" << key; | |
558 | 561 | value_str = btif_convert_to_encrypt_key(str); |
559 | 562 | } else { |
560 | 563 | value_str = str; |
@@ -17,6 +17,8 @@ | ||
17 | 17 | ******************************************************************************/ |
18 | 18 | |
19 | 19 | #include "btif_keystore.h" |
20 | +#include "keystore_client.pb.h" | |
21 | +#include "string.h" | |
20 | 22 | |
21 | 23 | #include <base/files/file_util.h> |
22 | 24 | #include <base/logging.h> |
@@ -29,7 +31,9 @@ | ||
29 | 31 | using namespace keystore; |
30 | 32 | using namespace bluetooth; |
31 | 33 | |
32 | -constexpr char kKeyStore[] = "AndroidKeystore"; | |
34 | +const std::string kKeyStore = "bluetooth-key-encrypted"; | |
35 | +constexpr uint32_t kAESKeySize = 256; // bits | |
36 | +constexpr uint32_t kMACOutputSize = 128; // bits | |
33 | 37 | |
34 | 38 | namespace bluetooth { |
35 | 39 |
@@ -43,19 +47,45 @@ std::string BtifKeystore::Encrypt(const std::string& data, int32_t flags) { | ||
43 | 47 | LOG(ERROR) << __func__ << ": empty data"; |
44 | 48 | return output; |
45 | 49 | } |
46 | - if (!keystore_client_->doesKeyExist(kKeyStore)) { | |
47 | - auto gen_result = GenerateKey(kKeyStore, 0, false); | |
48 | - if (!gen_result.isOk()) { | |
49 | - LOG(FATAL) << "EncryptWithAuthentication Failed: generateKey response=" | |
50 | - << gen_result; | |
51 | - return output; | |
52 | - } | |
50 | + if (!GenerateKey(kKeyStore, flags)) { | |
51 | + return output; | |
53 | 52 | } |
54 | - if (!keystore_client_->encryptWithAuthentication(kKeyStore, data, flags, | |
55 | - &output)) { | |
56 | - LOG(FATAL) << "EncryptWithAuthentication failed."; | |
53 | + | |
54 | + AuthorizationSetBuilder encrypt_params; | |
55 | + encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::GCM) | |
56 | + .Authorization(TAG_MAC_LENGTH, kMACOutputSize) | |
57 | + .Padding(PaddingMode::NONE); | |
58 | + AuthorizationSet output_params; | |
59 | + std::string raw_encrypted_data; | |
60 | + if (!keystore_client_->oneShotOperation( | |
61 | + KeyPurpose::ENCRYPT, kKeyStore, encrypt_params, data, | |
62 | + std::string() /* signature_to_verify */, &output_params, | |
63 | + &raw_encrypted_data)) { | |
64 | + LOG(ERROR) << __func__ << ": AES operation failed."; | |
57 | 65 | return output; |
58 | 66 | } |
67 | + auto init_vector_blob = output_params.GetTagValue(TAG_NONCE); | |
68 | + if (!init_vector_blob.isOk()) { | |
69 | + LOG(ERROR) << __func__ << ": Missing initialization vector."; | |
70 | + return output; | |
71 | + } | |
72 | + | |
73 | + const hidl_vec<uint8_t>& value = init_vector_blob.value(); | |
74 | + std::string init_vector = | |
75 | + std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), | |
76 | + value.size()); | |
77 | + | |
78 | + if (memcmp(&init_vector_blob, &init_vector, init_vector.length()) == 0) { | |
79 | + LOG(ERROR) << __func__ | |
80 | + << ": Protobuf nonce data doesn't match the actual nonce."; | |
81 | + } | |
82 | + | |
83 | + EncryptedData protobuf; | |
84 | + protobuf.set_init_vector(init_vector); | |
85 | + protobuf.set_encrypted_data(raw_encrypted_data); | |
86 | + if (!protobuf.SerializeToString(&output)) { | |
87 | + LOG(ERROR) << __func__ << ": Failed to serialize EncryptedData protobuf."; | |
88 | + } | |
59 | 89 | return output; |
60 | 90 | } |
61 | 91 |
@@ -66,36 +96,49 @@ std::string BtifKeystore::Decrypt(const std::string& input) { | ||
66 | 96 | return ""; |
67 | 97 | } |
68 | 98 | std::string output; |
69 | - if (!keystore_client_->decryptWithAuthentication(kKeyStore, input, &output)) { | |
70 | - LOG(FATAL) << "DecryptWithAuthentication failed.\n"; | |
99 | + EncryptedData protobuf; | |
100 | + if (!protobuf.ParseFromString(input)) { | |
101 | + LOG(ERROR) << __func__ << ": Failed to parse EncryptedData protobuf."; | |
102 | + return output; | |
103 | + } | |
104 | + AuthorizationSetBuilder encrypt_params; | |
105 | + encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::GCM) | |
106 | + .Authorization(TAG_MAC_LENGTH, kMACOutputSize) | |
107 | + .Authorization(TAG_NONCE, protobuf.init_vector().data(), | |
108 | + protobuf.init_vector().size()) | |
109 | + .Padding(PaddingMode::NONE); | |
110 | + AuthorizationSet output_params; | |
111 | + if (!keystore_client_->oneShotOperation( | |
112 | + KeyPurpose::DECRYPT, kKeyStore, encrypt_params, | |
113 | + protobuf.encrypted_data(), std::string() /* signature_to_verify */, | |
114 | + &output_params, &output)) { | |
115 | + LOG(ERROR) << __func__ << ": AES operation failed."; | |
71 | 116 | } |
72 | 117 | return output; |
73 | 118 | } |
74 | 119 | |
75 | -// Note: auth_bound keys created with this tool will not be usable. | |
76 | -KeyStoreNativeReturnCode BtifKeystore::GenerateKey(const std::string& name, | |
77 | - int32_t flags, | |
78 | - bool auth_bound) { | |
79 | - AuthorizationSetBuilder params; | |
80 | - params.RsaSigningKey(2048, 65537) | |
81 | - .Digest(Digest::SHA_2_224) | |
82 | - .Digest(Digest::SHA_2_256) | |
83 | - .Digest(Digest::SHA_2_384) | |
84 | - .Digest(Digest::SHA_2_512) | |
85 | - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN) | |
86 | - .Padding(PaddingMode::RSA_PSS); | |
87 | - if (auth_bound) { | |
88 | - // Gatekeeper normally generates the secure user id. | |
89 | - // Using zero allows the key to be created, but it will not be usuable. | |
90 | - params.Authorization(TAG_USER_SECURE_ID, 0); | |
91 | - } else { | |
92 | - params.Authorization(TAG_NO_AUTH_REQUIRED); | |
120 | +bool BtifKeystore::GenerateKey(const std::string& name, int32_t flags) { | |
121 | + if (!DoesKeyExist()) { | |
122 | + AuthorizationSetBuilder params; | |
123 | + params.AesEncryptionKey(kAESKeySize) | |
124 | + .Authorization(TAG_NO_AUTH_REQUIRED) | |
125 | + .Authorization(TAG_BLOCK_MODE, BlockMode::GCM) | |
126 | + .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT) | |
127 | + .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT) | |
128 | + .Padding(PaddingMode::NONE) | |
129 | + .Authorization(TAG_MIN_MAC_LENGTH, kMACOutputSize); | |
130 | + AuthorizationSet hardware_enforced_characteristics; | |
131 | + AuthorizationSet software_enforced_characteristics; | |
132 | + auto result = keystore_client_->generateKey( | |
133 | + name, params, flags, &hardware_enforced_characteristics, | |
134 | + &software_enforced_characteristics); | |
135 | + if (!result.isOk()) { | |
136 | + LOG(FATAL) << __func__ << "Failed to generate key: name: " << name | |
137 | + << ", error code: " << result.getErrorCode(); | |
138 | + return false; | |
139 | + } | |
93 | 140 | } |
94 | - AuthorizationSet hardware_enforced_characteristics; | |
95 | - AuthorizationSet software_enforced_characteristics; | |
96 | - return keystore_client_->generateKey(name, params, flags, | |
97 | - &hardware_enforced_characteristics, | |
98 | - &software_enforced_characteristics); | |
141 | + return true; | |
99 | 142 | } |
100 | 143 | |
101 | 144 | bool BtifKeystore::DoesKeyExist() { |