1 /*
2 * Copyright (C) 2020 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 #define LOG_TAG "keystore2"
18
19 #include "crypto.hpp"
20
21 #include <assert.h>
22 #include <log/log.h>
23 #include <openssl/aes.h>
24 #include <openssl/ec.h>
25 #include <openssl/ec_key.h>
26 #include <openssl/ecdh.h>
27 #include <openssl/evp.h>
28 #include <openssl/hkdf.h>
29 #include <openssl/hmac.h>
30 #include <openssl/rand.h>
31 #include <openssl/x509.h>
32
33 #include <vector>
34
35 // Copied from system/security/keystore/blob.h.
36
37 constexpr size_t kGcmTagLength = 128 / 8;
38 constexpr size_t kAes128KeySizeBytes = 128 / 8;
39
40 // Copied from system/security/keystore/blob.cpp.
41
42 #if defined(__clang__)
43 #define OPTNONE __attribute__((optnone))
44 #elif defined(__GNUC__)
45 #define OPTNONE __attribute__((optimize("O0")))
46 #else
47 #error Need a definition for OPTNONE
48 #endif
49
50 class ArrayEraser {
51 public:
ArrayEraser(uint8_t * arr,size_t size)52 ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
~ArrayEraser()53 OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
54
55 private:
56 volatile uint8_t* mArr;
57 size_t mSize;
58 };
59
60 /**
61 * Returns a EVP_CIPHER appropriate for the given key size.
62 */
getAesCipherForKey(size_t key_size)63 const EVP_CIPHER* getAesCipherForKey(size_t key_size) {
64 const EVP_CIPHER* cipher = EVP_aes_256_gcm();
65 if (key_size == kAes128KeySizeBytes) {
66 cipher = EVP_aes_128_gcm();
67 }
68 return cipher;
69 }
70
hmacSha256(const uint8_t * key,size_t key_size,const uint8_t * msg,size_t msg_size,uint8_t * out,size_t out_size)71 bool hmacSha256(const uint8_t* key, size_t key_size, const uint8_t* msg, size_t msg_size,
72 uint8_t* out, size_t out_size) {
73 const EVP_MD* digest = EVP_sha256();
74 unsigned int actual_out_size = out_size;
75 uint8_t* p = HMAC(digest, key, key_size, msg, msg_size, out, &actual_out_size);
76 return (p != nullptr);
77 }
78
randomBytes(uint8_t * out,size_t len)79 bool randomBytes(uint8_t* out, size_t len) {
80 return RAND_bytes(out, len);
81 }
82
83 /*
84 * Encrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
85 * 'iv' and write output to 'out' (which may be the same location as 'in') and 128-bit tag to
86 * 'tag'.
87 */
AES_gcm_encrypt(const uint8_t * in,uint8_t * out,size_t len,const uint8_t * key,size_t key_size,const uint8_t * iv,uint8_t * tag)88 bool AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
89 size_t key_size, const uint8_t* iv, uint8_t* tag) {
90
91 // There can be 128-bit and 256-bit keys
92 const EVP_CIPHER* cipher = getAesCipherForKey(key_size);
93
94 bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
95
96 EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
97 EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
98
99 std::vector<uint8_t> out_tmp(len);
100 uint8_t* out_pos = out_tmp.data();
101 int out_len;
102
103 EVP_EncryptUpdate(ctx.get(), out_pos, &out_len, in, len);
104 out_pos += out_len;
105 EVP_EncryptFinal_ex(ctx.get(), out_pos, &out_len);
106 out_pos += out_len;
107 if (out_pos - out_tmp.data() != static_cast<ssize_t>(len)) {
108 ALOGD("Encrypted ciphertext is the wrong size, expected %zu, got %zd", len,
109 out_pos - out_tmp.data());
110 return false;
111 }
112
113 std::copy(out_tmp.data(), out_pos, out);
114 EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kGcmTagLength, tag);
115
116 return true;
117 }
118
119 /*
120 * Decrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
121 * 'iv', checking 128-bit tag at 'tag' and writing plaintext to 'out'(which may be the same
122 * location as 'in').
123 */
AES_gcm_decrypt(const uint8_t * in,uint8_t * out,size_t len,const uint8_t * key,size_t key_size,const uint8_t * iv,const uint8_t * tag)124 bool AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
125 size_t key_size, const uint8_t* iv, const uint8_t* tag) {
126
127 // There can be 128-bit and 256-bit keys
128 const EVP_CIPHER* cipher = getAesCipherForKey(key_size);
129
130 bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
131
132 EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
133 EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
134 EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kGcmTagLength, const_cast<uint8_t*>(tag));
135
136 std::vector<uint8_t> out_tmp(len);
137 ArrayEraser out_eraser(out_tmp.data(), len);
138 uint8_t* out_pos = out_tmp.data();
139 int out_len;
140
141 EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
142 out_pos += out_len;
143 if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
144 ALOGE("Failed to decrypt blob; ciphertext or tag is likely corrupted");
145 return false;
146 }
147 out_pos += out_len;
148 if (out_pos - out_tmp.data() != static_cast<ssize_t>(len)) {
149 ALOGE("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
150 out_pos - out_tmp.data());
151 return false;
152 }
153
154 std::copy(out_tmp.data(), out_pos, out);
155
156 return true;
157 }
158
159 // Copied from system/security/keystore/keymaster_enforcement.cpp.
160
161 class EvpMdCtx {
162 public:
EvpMdCtx()163 EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
~EvpMdCtx()164 ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
165
get()166 EVP_MD_CTX* get() { return &ctx_; }
167
168 private:
169 EVP_MD_CTX ctx_;
170 };
171
CreateKeyId(const uint8_t * key_blob,size_t len,km_id_t * out_id)172 bool CreateKeyId(const uint8_t* key_blob, size_t len, km_id_t* out_id) {
173 EvpMdCtx ctx;
174
175 uint8_t hash[EVP_MAX_MD_SIZE];
176 unsigned int hash_len;
177 if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) &&
178 EVP_DigestUpdate(ctx.get(), key_blob, len) &&
179 EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) {
180 assert(hash_len >= sizeof(*out_id));
181 memcpy(out_id, hash, sizeof(*out_id));
182 return true;
183 }
184
185 return false;
186 }
187
188 // Copied from system/security/keystore/user_state.h
189
190 static constexpr size_t SALT_SIZE = 16;
191
192 // Copied from system/security/keystore/user_state.cpp.
193
generateKeyFromPassword(uint8_t * key,size_t key_len,const char * pw,size_t pw_len,const uint8_t * salt)194 void generateKeyFromPassword(uint8_t* key, size_t key_len, const char* pw, size_t pw_len,
195 const uint8_t* salt) {
196 const EVP_MD* digest = EVP_sha256();
197
198 // SHA1 was used prior to increasing the key size
199 if (key_len == kAes128KeySizeBytes) {
200 digest = EVP_sha1();
201 }
202
203 PKCS5_PBKDF2_HMAC(pw, pw_len, salt, SALT_SIZE, 8192, digest, key_len, key);
204 }
205
206 // New code.
207
HKDFExtract(uint8_t * out_key,size_t * out_len,const uint8_t * secret,size_t secret_len,const uint8_t * salt,size_t salt_len)208 bool HKDFExtract(uint8_t* out_key, size_t* out_len, const uint8_t* secret, size_t secret_len,
209 const uint8_t* salt, size_t salt_len) {
210 const EVP_MD* digest = EVP_sha256();
211 auto result = HKDF_extract(out_key, out_len, digest, secret, secret_len, salt, salt_len);
212 return result == 1;
213 }
214
HKDFExpand(uint8_t * out_key,size_t out_len,const uint8_t * prk,size_t prk_len,const uint8_t * info,size_t info_len)215 bool HKDFExpand(uint8_t* out_key, size_t out_len, const uint8_t* prk, size_t prk_len,
216 const uint8_t* info, size_t info_len) {
217 const EVP_MD* digest = EVP_sha256();
218 auto result = HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len);
219 return result == 1;
220 }
221
ECDHComputeKey(void * out,const EC_POINT * pub_key,const EC_KEY * priv_key)222 int ECDHComputeKey(void* out, const EC_POINT* pub_key, const EC_KEY* priv_key) {
223 return ECDH_compute_key(out, EC_MAX_BYTES, pub_key, priv_key, nullptr);
224 }
225
ECKEYGenerateKey()226 EC_KEY* ECKEYGenerateKey() {
227 EC_KEY* key = EC_KEY_new();
228 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
229 EC_KEY_set_group(key, group);
230 auto result = EC_KEY_generate_key(key);
231 if (result == 0) {
232 EC_GROUP_free(group);
233 EC_KEY_free(key);
234 return nullptr;
235 }
236 return key;
237 }
238
ECKEYMarshalPrivateKey(const EC_KEY * priv_key,uint8_t * buf,size_t len)239 size_t ECKEYMarshalPrivateKey(const EC_KEY* priv_key, uint8_t* buf, size_t len) {
240 CBB cbb;
241 size_t out_len;
242 if (!CBB_init_fixed(&cbb, buf, len) ||
243 !EC_KEY_marshal_private_key(&cbb, priv_key, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY) ||
244 !CBB_finish(&cbb, nullptr, &out_len)) {
245 return 0;
246 } else {
247 return out_len;
248 }
249 }
250
ECKEYParsePrivateKey(const uint8_t * buf,size_t len)251 EC_KEY* ECKEYParsePrivateKey(const uint8_t* buf, size_t len) {
252 CBS cbs;
253 CBS_init(&cbs, buf, len);
254 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
255 auto result = EC_KEY_parse_private_key(&cbs, group);
256 EC_GROUP_free(group);
257 if (result != nullptr && CBS_len(&cbs) != 0) {
258 EC_KEY_free(result);
259 return nullptr;
260 }
261 return result;
262 }
263
ECPOINTPoint2Oct(const EC_POINT * point,uint8_t * buf,size_t len)264 size_t ECPOINTPoint2Oct(const EC_POINT* point, uint8_t* buf, size_t len) {
265 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
266 point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
267 auto result = EC_POINT_point2oct(group, point, form, buf, len, nullptr);
268 EC_GROUP_free(group);
269 return result;
270 }
271
ECPOINTOct2Point(const uint8_t * buf,size_t len)272 EC_POINT* ECPOINTOct2Point(const uint8_t* buf, size_t len) {
273 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
274 EC_POINT* point = EC_POINT_new(group);
275 auto result = EC_POINT_oct2point(group, point, buf, len, nullptr);
276 EC_GROUP_free(group);
277 if (result == 0) {
278 EC_POINT_free(point);
279 return nullptr;
280 }
281 return point;
282 }
283
extractSubjectFromCertificate(const uint8_t * cert_buf,size_t cert_len,uint8_t * subject_buf,size_t subject_buf_len)284 int extractSubjectFromCertificate(const uint8_t* cert_buf, size_t cert_len, uint8_t* subject_buf,
285 size_t subject_buf_len) {
286 if (!cert_buf || !subject_buf) {
287 ALOGE("extractSubjectFromCertificate: received null pointer");
288 return 0;
289 }
290
291 const uint8_t* p = cert_buf;
292 bssl::UniquePtr<X509> cert(d2i_X509(nullptr /* Allocate X509 struct */, &p, cert_len));
293 if (!cert) {
294 ALOGE("extractSubjectFromCertificate: failed to parse certificate");
295 return 0;
296 }
297
298 X509_NAME* subject = X509_get_subject_name(cert.get());
299 if (!subject) {
300 ALOGE("extractSubjectFromCertificate: failed to retrieve subject name");
301 return 0;
302 }
303
304 int subject_len = i2d_X509_NAME(subject, nullptr /* Don't copy the data */);
305 if (subject_len < 0) {
306 ALOGE("extractSubjectFromCertificate: error obtaining encoded subject name length");
307 return 0;
308 }
309
310 if (subject_len > subject_buf_len) {
311 // Return the subject length, negated, so the caller knows how much
312 // buffer space is required.
313 ALOGI("extractSubjectFromCertificate: needed %d bytes for subject, caller provided %zu",
314 subject_len, subject_buf_len);
315 return -subject_len;
316 }
317
318 // subject_buf has enough space.
319 uint8_t* tmp = subject_buf;
320 return i2d_X509_NAME(subject, &tmp);
321 }
322