• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include <keymaster/key_blob_utils/auth_encrypted_key_blob.h>
18 
19 #include <utility>
20 
21 #include <openssl/digest.h>
22 #include <openssl/evp.h>
23 #include <openssl/hkdf.h>
24 
25 #include <keymaster/android_keymaster_utils.h>
26 #include <keymaster/authorization_set.h>
27 #include <keymaster/key_blob_utils/ocb_utils.h>
28 #include <keymaster/km_openssl/openssl_err.h>
29 #include <keymaster/logger.h>
30 #include <keymaster/random_source.h>
31 
32 namespace keymaster {
33 
34 namespace {
35 
36 constexpr uint8_t kAesGcmDescriptor1[] = "AES-256-GCM-HKDF-SHA-256, version 1";
37 constexpr uint8_t kAesGcmDescriptor2[] = "AES-256-GCM-HKDF-SHA-256, version 2";
38 constexpr size_t kAesGcmNonceLength = 12;
39 constexpr size_t kAesGcmTagLength = 16;
40 constexpr size_t kAes256KeyLength = 256 / 8;
41 
generate_nonce(const RandomSource & random,size_t size)42 KmErrorOr<Buffer> generate_nonce(const RandomSource& random, size_t size) {
43     Buffer nonce;
44     if (!nonce.Reinitialize(size)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
45 
46     random.GenerateRandom(nonce.peek_write(), size);
47     nonce.advance_write(size);
48     return nonce;
49 }
50 
BuildDerivationInfo(const AuthEncryptedBlobFormat format,const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,const AuthorizationSet & hidden,const SecureDeletionData & secure_deletion_data)51 KmErrorOr<Buffer> BuildDerivationInfo(const AuthEncryptedBlobFormat format,  //
52                                       const AuthorizationSet& hw_enforced,   //
53                                       const AuthorizationSet& sw_enforced,   //
54                                       const AuthorizationSet& hidden,
55                                       const SecureDeletionData& secure_deletion_data) {
56     bool use_sdd = requiresSecureDeletion(format);
57 
58     size_t info_len =
59         hidden.SerializedSize() + hw_enforced.SerializedSize() + sw_enforced.SerializedSize();
60     if (use_sdd) {
61         info_len += sizeof(kAesGcmDescriptor2) +
62                     secure_deletion_data.factory_reset_secret.SerializedSize() +
63                     secure_deletion_data.secure_deletion_secret.SerializedSize() +
64                     sizeof(secure_deletion_data.key_slot);
65     } else {
66         info_len += sizeof(kAesGcmDescriptor1);
67     }
68 
69     Buffer info(info_len);
70     info.write(use_sdd ? kAesGcmDescriptor2 : kAesGcmDescriptor1);
71     uint8_t* buf = info.peek_write();
72     const uint8_t* end = info.peek_write() + info.available_write();
73     buf = hidden.Serialize(buf, end);
74     buf = hw_enforced.Serialize(buf, end);
75     buf = sw_enforced.Serialize(buf, end);
76 
77     if (use_sdd) {
78         buf = secure_deletion_data.factory_reset_secret.Serialize(buf, end);
79         buf = secure_deletion_data.secure_deletion_secret.Serialize(buf, end);
80         static_assert(std::is_same_v<decltype(secure_deletion_data.key_slot), uint32_t>);
81         buf = append_uint32_to_buf(buf, end, secure_deletion_data.key_slot);
82     }
83 
84     if (!buf || buf != end || !info.advance_write(buf - info.peek_write())) {
85         LOG_S("Buffer management error", 0);
86         return KM_ERROR_UNKNOWN_ERROR;
87     }
88 
89     return info;
90 }
91 
DeriveAesGcmKeyEncryptionKey(const AuthEncryptedBlobFormat format,const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,const AuthorizationSet & hidden,const SecureDeletionData & secure_deletion_data,const KeymasterKeyBlob & master_key)92 KmErrorOr<Buffer> DeriveAesGcmKeyEncryptionKey(const AuthEncryptedBlobFormat format,            //
93                                                const AuthorizationSet& hw_enforced,             //
94                                                const AuthorizationSet& sw_enforced,             //
95                                                const AuthorizationSet& hidden,                  //
96                                                const SecureDeletionData& secure_deletion_data,  //
97                                                const KeymasterKeyBlob& master_key) {
98     Buffer prk(EVP_MAX_MD_SIZE);
99     size_t out_len = EVP_MAX_MD_SIZE;
100     if (!HKDF_extract(prk.peek_write(), &out_len, EVP_sha256(), master_key.key_material,
101                       master_key.key_material_size, nullptr /* salt */, 0 /* salt_len */)) {
102         return TranslateLastOpenSslError();
103     }
104 
105     KmErrorOr<Buffer> info =
106         BuildDerivationInfo(format, hw_enforced, sw_enforced, hidden, secure_deletion_data);
107     if (!info) return info.error();
108 
109     if (!prk.advance_write(out_len) || !prk.available_read() || !info->available_read()) {
110         return KM_ERROR_UNKNOWN_ERROR;
111     }
112 
113     Buffer keyEncryptionKey(kAes256KeyLength);
114     if (!HKDF_expand(keyEncryptionKey.peek_write(), keyEncryptionKey.available_write(),  //
115                      EVP_sha256(),                                                       //
116                      prk.peek_read(), prk.available_read(),                              //
117                      info->peek_read(), info->available_read())) {
118         return TranslateLastOpenSslError();
119     }
120 
121     return keyEncryptionKey;
122 }
123 
AesGcmEncryptKey(const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,const AuthorizationSet & hidden,const SecureDeletionData & secure_deletion_data,const KeymasterKeyBlob & master_key,const KeymasterKeyBlob & plaintext,const AuthEncryptedBlobFormat format,Buffer nonce)124 KmErrorOr<EncryptedKey> AesGcmEncryptKey(const AuthorizationSet& hw_enforced,             //
125                                          const AuthorizationSet& sw_enforced,             //
126                                          const AuthorizationSet& hidden,                  //
127                                          const SecureDeletionData& secure_deletion_data,  //
128                                          const KeymasterKeyBlob& master_key,              //
129                                          const KeymasterKeyBlob& plaintext,               //
130                                          const AuthEncryptedBlobFormat format,            //
131                                          Buffer nonce) {
132     KmErrorOr<Buffer> kek = DeriveAesGcmKeyEncryptionKey(format, hw_enforced, sw_enforced, hidden,
133                                                          secure_deletion_data, master_key);
134     if (!kek) return kek.error();
135 
136     bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
137     if (!ctx) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
138 
139     int ciphertext_len = plaintext.size();
140     int unused_len = 0;
141     EncryptedKey retval;
142     retval.format = format;
143     retval.ciphertext = KeymasterKeyBlob(ciphertext_len);
144     retval.nonce = std::move(nonce);
145     retval.tag = Buffer(kAesGcmTagLength);
146 
147     if (!(EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr /* engine */, kek->peek_read(),
148                              retval.nonce.peek_read()) &&
149           EVP_EncryptUpdate(ctx.get(), retval.ciphertext.writable_data(), &ciphertext_len,
150                             plaintext.key_material, plaintext.size()) &&
151           EVP_EncryptFinal_ex(ctx.get(), retval.ciphertext.writable_data() /* not written to */,
152                               &unused_len) &&
153           EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAesGcmTagLength,
154                               retval.tag.peek_write()))) {
155         return TranslateLastOpenSslError();
156     }
157 
158     if (plaintext.size() != static_cast<size_t>(ciphertext_len) || 0 != unused_len ||
159         !retval.tag.advance_write(kAesGcmTagLength)) {
160         return KM_ERROR_UNKNOWN_ERROR;
161     }
162 
163     return retval;
164 }
165 
AesGcmDecryptKey(const DeserializedKey & key,const AuthorizationSet & hidden,const SecureDeletionData & secure_deletion_data,const KeymasterKeyBlob & master_key)166 KmErrorOr<KeymasterKeyBlob> AesGcmDecryptKey(const DeserializedKey& key,
167                                              const AuthorizationSet& hidden,
168                                              const SecureDeletionData& secure_deletion_data,
169                                              const KeymasterKeyBlob& master_key) {
170     KmErrorOr<Buffer> kek =
171         DeriveAesGcmKeyEncryptionKey(key.encrypted_key.format, key.hw_enforced, key.sw_enforced,
172                                      hidden, secure_deletion_data, master_key);
173     if (!kek) return kek.error();
174 
175     bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
176     if (!ctx) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
177 
178     int plaintext_len = key.encrypted_key.ciphertext.size();
179     int unused_len = 0;
180     KeymasterKeyBlob plaintext(plaintext_len);
181     if (!(EVP_DecryptInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr /* engine */, kek->peek_read(),
182                              key.encrypted_key.nonce.peek_read()) &&
183           EVP_DecryptUpdate(ctx.get(), plaintext.writable_data(), &plaintext_len,
184                             key.encrypted_key.ciphertext.key_material,
185                             key.encrypted_key.ciphertext.size()) &&
186           EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kAesGcmTagLength,
187                               const_cast<uint8_t*>(key.encrypted_key.tag.peek_read())))) {
188         return TranslateLastOpenSslError();
189     }
190 
191     if (!EVP_DecryptFinal_ex(ctx.get(), plaintext.writable_data() /* not written to */,
192                              &unused_len)) {
193         return KM_ERROR_INVALID_KEY_BLOB;
194     }
195 
196     if (key.encrypted_key.ciphertext.size() != plaintext.size() || 0 != unused_len) {
197         return KM_ERROR_UNKNOWN_ERROR;
198     }
199 
200     return plaintext;
201 }
202 
203 }  // namespace
204 
SerializeAuthEncryptedBlob(const EncryptedKey & encrypted_key,const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,uint32_t key_slot)205 KmErrorOr<KeymasterKeyBlob> SerializeAuthEncryptedBlob(const EncryptedKey& encrypted_key,
206                                                        const AuthorizationSet& hw_enforced,
207                                                        const AuthorizationSet& sw_enforced,
208                                                        uint32_t key_slot) {
209     bool use_key_slot = requiresSecureDeletion(encrypted_key.format);
210 
211     size_t size = 1 /* version byte */ + encrypted_key.nonce.SerializedSize() +
212                   encrypted_key.ciphertext.SerializedSize() + encrypted_key.tag.SerializedSize() +
213                   hw_enforced.SerializedSize() + sw_enforced.SerializedSize();
214     if (use_key_slot) size += sizeof(key_slot);
215     if (isVersionedFormat(encrypted_key.format)) {
216         size += sizeof(encrypted_key.kdf_version);
217         size += sizeof(encrypted_key.addl_info);
218     }
219     KeymasterKeyBlob retval;
220     if (!retval.Reset(size)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
221 
222     uint8_t* buf = retval.writable_data();
223     const uint8_t* end = retval.end();
224 
225     *buf++ = encrypted_key.format;
226     buf = encrypted_key.nonce.Serialize(buf, end);
227     buf = encrypted_key.ciphertext.Serialize(buf, end);
228     buf = encrypted_key.tag.Serialize(buf, end);
229     if (isVersionedFormat(encrypted_key.format)) {
230         buf = append_uint32_to_buf(buf, end, encrypted_key.kdf_version);
231         buf = append_uint32_to_buf(buf, end, encrypted_key.addl_info);
232     }
233     buf = hw_enforced.Serialize(buf, end);
234     buf = sw_enforced.Serialize(buf, end);
235     if (use_key_slot) buf = append_uint32_to_buf(buf, end, key_slot);
236 
237     if (buf != retval.end()) return KM_ERROR_UNKNOWN_ERROR;
238 
239     return retval;
240 }
241 
DeserializeAuthEncryptedBlob(const KeymasterKeyBlob & key_blob)242 KmErrorOr<DeserializedKey> DeserializeAuthEncryptedBlob(const KeymasterKeyBlob& key_blob) {
243     if (!key_blob.key_material || key_blob.key_material_size == 0) return KM_ERROR_INVALID_KEY_BLOB;
244 
245     const uint8_t* tmp = key_blob.key_material;
246     const uint8_t** buf_ptr = &tmp;
247     const uint8_t* end = tmp + key_blob.key_material_size;
248 
249     if (end <= *buf_ptr) return KM_ERROR_INVALID_KEY_BLOB;
250 
251     DeserializedKey retval{};
252     retval.encrypted_key.format = static_cast<AuthEncryptedBlobFormat>(*(*buf_ptr)++);
253     if (!retval.encrypted_key.nonce.Deserialize(buf_ptr, end) ||       //
254         !retval.encrypted_key.ciphertext.Deserialize(buf_ptr, end) ||  //
255         !retval.encrypted_key.tag.Deserialize(buf_ptr, end)) {
256         return KM_ERROR_INVALID_KEY_BLOB;
257     }
258 
259     if (isVersionedFormat(retval.encrypted_key.format)) {
260         if (!copy_uint32_from_buf(buf_ptr, end, &retval.encrypted_key.kdf_version) ||
261             !copy_uint32_from_buf(buf_ptr, end, &retval.encrypted_key.addl_info)) {
262             return KM_ERROR_INVALID_KEY_BLOB;
263         }
264     }
265 
266     if (!retval.hw_enforced.Deserialize(buf_ptr, end) ||  //
267         !retval.sw_enforced.Deserialize(buf_ptr, end)) {
268         return KM_ERROR_INVALID_KEY_BLOB;
269     }
270 
271     if (requiresSecureDeletion(retval.encrypted_key.format)) {
272         if (!copy_uint32_from_buf(buf_ptr, end, &retval.key_slot)) {
273             return KM_ERROR_INVALID_KEY_BLOB;
274         }
275     }
276 
277     if (*buf_ptr != end) return KM_ERROR_INVALID_KEY_BLOB;
278 
279     switch (retval.encrypted_key.format) {
280     case AES_OCB:
281         if (retval.encrypted_key.nonce.available_read() != OCB_NONCE_LENGTH ||
282             retval.encrypted_key.tag.available_read() != OCB_TAG_LENGTH) {
283             return KM_ERROR_INVALID_KEY_BLOB;
284         }
285         return retval;
286 
287     case AES_GCM_WITH_SW_ENFORCED:
288     case AES_GCM_WITH_SECURE_DELETION:
289     case AES_GCM_WITH_SW_ENFORCED_VERSIONED:
290     case AES_GCM_WITH_SECURE_DELETION_VERSIONED:
291         if (retval.encrypted_key.nonce.available_read() != kAesGcmNonceLength ||
292             retval.encrypted_key.tag.available_read() != kAesGcmTagLength) {
293             return KM_ERROR_INVALID_KEY_BLOB;
294         }
295         return retval;
296     }
297 
298     LOG_E("Invalid key blob format %d", retval.encrypted_key.format);
299     return KM_ERROR_INVALID_KEY_BLOB;
300 }
301 
302 KmErrorOr<EncryptedKey>
EncryptKey(const KeymasterKeyBlob & plaintext,AuthEncryptedBlobFormat format,const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,const AuthorizationSet & hidden,const SecureDeletionData & secure_deletion_data,const KeymasterKeyBlob & master_key,const RandomSource & random)303 EncryptKey(const KeymasterKeyBlob& plaintext, AuthEncryptedBlobFormat format,
304            const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
305            const AuthorizationSet& hidden, const SecureDeletionData& secure_deletion_data,
306            const KeymasterKeyBlob& master_key, const RandomSource& random) {
307     switch (format) {
308     case AES_OCB: {
309         EncryptedKey retval;
310         retval.format = format;
311         auto nonce = generate_nonce(random, OCB_NONCE_LENGTH);
312         if (!nonce) return nonce.error();
313         retval.nonce = std::move(*nonce);
314         retval.tag.Reinitialize(OCB_TAG_LENGTH);
315         keymaster_error_t error =
316             OcbEncryptKey(hw_enforced, sw_enforced, hidden, master_key, plaintext, retval.nonce,
317                           &retval.ciphertext, &retval.tag);
318         if (error != KM_ERROR_OK) return error;
319         return retval;
320     }
321 
322     case AES_GCM_WITH_SW_ENFORCED:
323     case AES_GCM_WITH_SECURE_DELETION:
324     case AES_GCM_WITH_SW_ENFORCED_VERSIONED:
325     case AES_GCM_WITH_SECURE_DELETION_VERSIONED: {
326         auto nonce = generate_nonce(random, kAesGcmNonceLength);
327         if (!nonce) return nonce.error();
328         return AesGcmEncryptKey(hw_enforced, sw_enforced, hidden, secure_deletion_data, master_key,
329                                 plaintext, format, std::move(*nonce));
330     }
331     }
332 
333     LOG_E("Invalid key blob format %d", format);
334     return KM_ERROR_UNKNOWN_ERROR;
335 }
336 
DecryptKey(const DeserializedKey & key,const AuthorizationSet & hidden,const SecureDeletionData & secure_deletion_data,const KeymasterKeyBlob & master_key)337 KmErrorOr<KeymasterKeyBlob> DecryptKey(const DeserializedKey& key, const AuthorizationSet& hidden,
338                                        const SecureDeletionData& secure_deletion_data,
339                                        const KeymasterKeyBlob& master_key) {
340     KeymasterKeyBlob retval;
341     switch (key.encrypted_key.format) {
342     case AES_OCB: {
343         keymaster_error_t error = OcbDecryptKey(
344             key.hw_enforced, key.sw_enforced, hidden, master_key, key.encrypted_key.ciphertext,
345             key.encrypted_key.nonce, key.encrypted_key.tag, &retval);
346         if (error != KM_ERROR_OK) return error;
347         return retval;
348     }
349 
350     case AES_GCM_WITH_SW_ENFORCED:
351     case AES_GCM_WITH_SECURE_DELETION:
352     case AES_GCM_WITH_SW_ENFORCED_VERSIONED:
353     case AES_GCM_WITH_SECURE_DELETION_VERSIONED:
354         return AesGcmDecryptKey(key, hidden, secure_deletion_data, master_key);
355     }
356 
357     LOG_E("Invalid key blob format %d", key.encrypted_key.format);
358     return KM_ERROR_INVALID_KEY_BLOB;
359 }
360 
requiresSecureDeletion(const AuthEncryptedBlobFormat & fmt)361 bool requiresSecureDeletion(const AuthEncryptedBlobFormat& fmt) {
362     return fmt == AES_GCM_WITH_SECURE_DELETION || fmt == AES_GCM_WITH_SECURE_DELETION_VERSIONED;
363 }
364 
isVersionedFormat(const AuthEncryptedBlobFormat & fmt)365 bool isVersionedFormat(const AuthEncryptedBlobFormat& fmt) {
366     return fmt == AES_GCM_WITH_SW_ENFORCED_VERSIONED ||
367            fmt == AES_GCM_WITH_SECURE_DELETION_VERSIONED;
368 }
369 
370 }  // namespace keymaster
371