blob: 2e613fdac9763650c4b22e926f6775a71b9477c2 [file] [log] [blame]
Joel Galensonca0efb12020-10-01 14:32:30 -07001/*
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 <log/log.h>
22#include <openssl/aes.h>
Joel Galenson05914582021-01-08 09:30:41 -080023#include <openssl/ec.h>
24#include <openssl/ec_key.h>
25#include <openssl/ecdh.h>
Joel Galensonca0efb12020-10-01 14:32:30 -070026#include <openssl/evp.h>
Joel Galenson05914582021-01-08 09:30:41 -080027#include <openssl/hkdf.h>
Janis Danisevskis9d90b812020-11-25 21:02:11 -080028#include <openssl/rand.h>
Shawn Willden8fde4c22021-02-14 13:58:22 -070029#include <openssl/x509.h>
Joel Galensonca0efb12020-10-01 14:32:30 -070030
31#include <vector>
32
33// Copied from system/security/keystore/blob.h.
34
35constexpr size_t kGcmTagLength = 128 / 8;
36constexpr size_t kAes128KeySizeBytes = 128 / 8;
37
38// Copied from system/security/keystore/blob.cpp.
39
40#if defined(__clang__)
41#define OPTNONE __attribute__((optnone))
42#elif defined(__GNUC__)
43#define OPTNONE __attribute__((optimize("O0")))
44#else
45#error Need a definition for OPTNONE
46#endif
47
48class ArrayEraser {
49 public:
50 ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
51 OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
52
53 private:
54 volatile uint8_t* mArr;
55 size_t mSize;
56};
57
58/**
59 * Returns a EVP_CIPHER appropriate for the given key size.
60 */
61const EVP_CIPHER* getAesCipherForKey(size_t key_size) {
62 const EVP_CIPHER* cipher = EVP_aes_256_gcm();
63 if (key_size == kAes128KeySizeBytes) {
64 cipher = EVP_aes_128_gcm();
65 }
66 return cipher;
67}
68
Janis Danisevskis9d90b812020-11-25 21:02:11 -080069bool randomBytes(uint8_t* out, size_t len) {
70 return RAND_bytes(out, len);
71}
72
Joel Galensonca0efb12020-10-01 14:32:30 -070073/*
74 * Encrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
75 * 'iv' and write output to 'out' (which may be the same location as 'in') and 128-bit tag to
76 * 'tag'.
77 */
78bool AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
79 size_t key_size, const uint8_t* iv, uint8_t* tag) {
80
81 // There can be 128-bit and 256-bit keys
82 const EVP_CIPHER* cipher = getAesCipherForKey(key_size);
83
84 bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
85
86 EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
87 EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
88
89 std::vector<uint8_t> out_tmp(len);
90 uint8_t* out_pos = out_tmp.data();
91 int out_len;
92
93 EVP_EncryptUpdate(ctx.get(), out_pos, &out_len, in, len);
94 out_pos += out_len;
95 EVP_EncryptFinal_ex(ctx.get(), out_pos, &out_len);
96 out_pos += out_len;
97 if (out_pos - out_tmp.data() != static_cast<ssize_t>(len)) {
98 ALOGD("Encrypted ciphertext is the wrong size, expected %zu, got %zd", len,
99 out_pos - out_tmp.data());
100 return false;
101 }
102
103 std::copy(out_tmp.data(), out_pos, out);
104 EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kGcmTagLength, tag);
105
106 return true;
107}
108
109/*
110 * Decrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
111 * 'iv', checking 128-bit tag at 'tag' and writing plaintext to 'out'(which may be the same
112 * location as 'in').
113 */
114bool AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
115 size_t key_size, const uint8_t* iv, const uint8_t* tag) {
116
117 // There can be 128-bit and 256-bit keys
118 const EVP_CIPHER* cipher = getAesCipherForKey(key_size);
119
120 bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
121
122 EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
123 EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
124 EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kGcmTagLength, const_cast<uint8_t*>(tag));
125
126 std::vector<uint8_t> out_tmp(len);
127 ArrayEraser out_eraser(out_tmp.data(), len);
128 uint8_t* out_pos = out_tmp.data();
129 int out_len;
130
131 EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
132 out_pos += out_len;
133 if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
134 ALOGE("Failed to decrypt blob; ciphertext or tag is likely corrupted");
135 return false;
136 }
137 out_pos += out_len;
138 if (out_pos - out_tmp.data() != static_cast<ssize_t>(len)) {
139 ALOGE("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
140 out_pos - out_tmp.data());
141 return false;
142 }
143
144 std::copy(out_tmp.data(), out_pos, out);
145
146 return true;
147}
148
149// Copied from system/security/keystore/keymaster_enforcement.cpp.
150
151class EvpMdCtx {
152 public:
153 EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
154 ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
155
156 EVP_MD_CTX* get() { return &ctx_; }
157
158 private:
159 EVP_MD_CTX ctx_;
160};
161
162bool CreateKeyId(const uint8_t* key_blob, size_t len, km_id_t* out_id) {
163 EvpMdCtx ctx;
164
165 uint8_t hash[EVP_MAX_MD_SIZE];
166 unsigned int hash_len;
167 if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) &&
168 EVP_DigestUpdate(ctx.get(), key_blob, len) &&
169 EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) {
170 assert(hash_len >= sizeof(*out_id));
171 memcpy(out_id, hash, sizeof(*out_id));
172 return true;
173 }
174
175 return false;
176}
177
178// Copied from system/security/keystore/user_state.h
179
180static constexpr size_t SALT_SIZE = 16;
181
182// Copied from system/security/keystore/user_state.cpp.
183
184void generateKeyFromPassword(uint8_t* key, size_t key_len, const char* pw, size_t pw_len,
Janis Danisevskis9d90b812020-11-25 21:02:11 -0800185 const uint8_t* salt) {
Joel Galensonca0efb12020-10-01 14:32:30 -0700186 size_t saltSize;
187 if (salt != nullptr) {
188 saltSize = SALT_SIZE;
189 } else {
190 // Pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
Janis Danisevskis9d90b812020-11-25 21:02:11 -0800191 salt = reinterpret_cast<const uint8_t*>("keystore");
Joel Galensonca0efb12020-10-01 14:32:30 -0700192 // sizeof = 9, not strlen = 8
193 saltSize = sizeof("keystore");
194 }
195
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, saltSize, 8192, digest, key_len, key);
204}
Joel Galenson05914582021-01-08 09:30:41 -0800205
206// New code.
207
208bool 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
215bool 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
222int 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
226EC_KEY* ECKEYGenerateKey() {
227 EC_KEY* key = EC_KEY_new();
228 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
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
239EC_KEY* ECKEYDeriveFromSecret(const uint8_t* secret, size_t secret_len) {
240 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
241 auto result = EC_KEY_derive_from_secret(group, secret, secret_len);
242 EC_GROUP_free(group);
243 return result;
244}
245
246size_t ECPOINTPoint2Oct(const EC_POINT* point, uint8_t* buf, size_t len) {
247 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
248 point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
249 auto result = EC_POINT_point2oct(group, point, form, buf, len, nullptr);
250 EC_GROUP_free(group);
251 return result;
252}
253
254EC_POINT* ECPOINTOct2Point(const uint8_t* buf, size_t len) {
255 EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
256 EC_POINT* point = EC_POINT_new(group);
257 auto result = EC_POINT_oct2point(group, point, buf, len, nullptr);
258 EC_GROUP_free(group);
259 if (result == 0) {
260 EC_POINT_free(point);
261 return nullptr;
262 }
263 return point;
264}
Shawn Willden8fde4c22021-02-14 13:58:22 -0700265
266int extractSubjectFromCertificate(const uint8_t* cert_buf, size_t cert_len, uint8_t* subject_buf,
267 size_t subject_buf_len) {
268 if (!cert_buf || !subject_buf) {
269 ALOGE("extractSubjectFromCertificate: received null pointer");
270 return 0;
271 }
272
273 const uint8_t* p = cert_buf;
274 bssl::UniquePtr<X509> cert(d2i_X509(nullptr /* Allocate X509 struct */, &p, cert_len));
275 if (!cert) {
276 ALOGE("extractSubjectFromCertificate: failed to parse certificate");
277 return 0;
278 }
279
280 X509_NAME* subject = X509_get_subject_name(cert.get());
281 if (!subject) {
282 ALOGE("extractSubjectFromCertificate: failed to retrieve subject name");
283 return 0;
284 }
285
286 int subject_len = i2d_X509_NAME(subject, nullptr /* Don't copy the data */);
287 if (subject_len < 0) {
288 ALOGE("extractSubjectFromCertificate: error obtaining encoded subject name length");
289 return 0;
290 }
291
292 if (subject_len > subject_buf_len) {
293 // Return the subject length, negated, so the caller knows how much
294 // buffer space is required.
295 ALOGI("extractSubjectFromCertificate: needed %d bytes for subject, caller provided %zu",
296 subject_len, subject_buf_len);
297 return -subject_len;
298 }
299
300 // subject_buf has enough space.
301 uint8_t* tmp = subject_buf;
302 return i2d_X509_NAME(subject, &tmp);
303}