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