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