1/* 2 * Copyright 2014 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 "asymmetric_key.h" 18 19#include <new> 20 21#include <openssl/asn1.h> 22#include <openssl/stack.h> 23#include <openssl/x509.h> 24#include <openssl/x509v3.h> 25 26#include "attestation_record.h" 27#include "openssl_err.h" 28#include "openssl_utils.h" 29 30namespace keymaster { 31 32namespace { 33 34constexpr int kDigitalSignatureKeyUsageBit = 0; 35constexpr int kKeyEnciphermentKeyUsageBit = 2; 36constexpr int kDataEnciphermentKeyUsageBit = 3; 37constexpr int kMaxKeyUsageBit = 8; 38 39template <typename T> T min(T a, T b) { 40 return (a < b) ? a : b; 41} 42 43static keymaster_error_t add_key_usage_extension(const AuthorizationSet& tee_enforced, 44 const AuthorizationSet& sw_enforced, 45 X509* certificate) { 46 // Build BIT_STRING with correct contents. 47 ASN1_BIT_STRING_Ptr key_usage(ASN1_BIT_STRING_new()); 48 49 for (size_t i = 0; i <= kMaxKeyUsageBit; ++i) { 50 if (!ASN1_BIT_STRING_set_bit(key_usage.get(), i, 0)) { 51 return TranslateLastOpenSslError(); 52 } 53 } 54 55 if (tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_SIGN) || 56 tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_VERIFY) || 57 sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_SIGN) || 58 sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_VERIFY)) { 59 if (!ASN1_BIT_STRING_set_bit(key_usage.get(), kDigitalSignatureKeyUsageBit, 1)) { 60 return TranslateLastOpenSslError(); 61 } 62 } 63 64 if (tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_ENCRYPT) || 65 tee_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_DECRYPT) || 66 sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_ENCRYPT) || 67 sw_enforced.Contains(TAG_PURPOSE, KM_PURPOSE_DECRYPT)) { 68 if (!ASN1_BIT_STRING_set_bit(key_usage.get(), kKeyEnciphermentKeyUsageBit, 1) || 69 !ASN1_BIT_STRING_set_bit(key_usage.get(), kDataEnciphermentKeyUsageBit, 1)) { 70 return TranslateLastOpenSslError(); 71 } 72 } 73 74 // Convert to octets 75 int len = i2d_ASN1_BIT_STRING(key_usage.get(), nullptr); 76 if (len < 0) { 77 return TranslateLastOpenSslError(); 78 } 79 UniquePtr<uint8_t[]> asn1_key_usage(new uint8_t[len]); 80 if (!asn1_key_usage.get()) { 81 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 82 } 83 uint8_t* p = asn1_key_usage.get(); 84 len = i2d_ASN1_BIT_STRING(key_usage.get(), &p); 85 if (len < 0) { 86 return TranslateLastOpenSslError(); 87 } 88 89 // Build OCTET_STRING 90 ASN1_OCTET_STRING_Ptr key_usage_str(ASN1_OCTET_STRING_new()); 91 if (!key_usage_str.get() || 92 !ASN1_OCTET_STRING_set(key_usage_str.get(), asn1_key_usage.get(), len)) { 93 return TranslateLastOpenSslError(); 94 } 95 96 X509_EXTENSION_Ptr key_usage_extension(X509_EXTENSION_create_by_NID(nullptr, // 97 NID_key_usage, // 98 false /* critical */, 99 key_usage_str.get())); 100 if (!key_usage_extension.get()) { 101 return TranslateLastOpenSslError(); 102 } 103 104 if (!X509_add_ext(certificate, key_usage_extension.get() /* Don't release; copied */, 105 -1 /* insert at end */)) { 106 return TranslateLastOpenSslError(); 107 } 108 109 return KM_ERROR_OK; 110} 111 112} // anonymous namespace 113 114keymaster_error_t AsymmetricKey::formatted_key_material(keymaster_key_format_t format, 115 UniquePtr<uint8_t[]>* material, 116 size_t* size) const { 117 if (format != KM_KEY_FORMAT_X509) 118 return KM_ERROR_UNSUPPORTED_KEY_FORMAT; 119 120 if (material == NULL || size == NULL) 121 return KM_ERROR_OUTPUT_PARAMETER_NULL; 122 123 EVP_PKEY_Ptr pkey(EVP_PKEY_new()); 124 if (!InternalToEvp(pkey.get())) 125 return TranslateLastOpenSslError(); 126 127 int key_data_length = i2d_PUBKEY(pkey.get(), NULL); 128 if (key_data_length <= 0) 129 return TranslateLastOpenSslError(); 130 131 material->reset(new (std::nothrow) uint8_t[key_data_length]); 132 if (material->get() == NULL) 133 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 134 135 uint8_t* tmp = material->get(); 136 if (i2d_PUBKEY(pkey.get(), &tmp) != key_data_length) { 137 material->reset(); 138 return TranslateLastOpenSslError(); 139 } 140 141 *size = key_data_length; 142 return KM_ERROR_OK; 143} 144 145static keymaster_error_t build_attestation_extension(const AuthorizationSet& attest_params, 146 const AuthorizationSet& tee_enforced, 147 const AuthorizationSet& sw_enforced, 148 const KeymasterContext& context, 149 X509_EXTENSION_Ptr* extension) { 150 ASN1_OBJECT_Ptr oid( 151 OBJ_txt2obj(kAttestionRecordOid, 1 /* accept numerical dotted string form only */)); 152 if (!oid.get()) 153 return TranslateLastOpenSslError(); 154 155 UniquePtr<uint8_t[]> attest_bytes; 156 size_t attest_bytes_len; 157 keymaster_error_t error = build_attestation_record(attest_params, sw_enforced, tee_enforced, 158 context, &attest_bytes, &attest_bytes_len); 159 if (error != KM_ERROR_OK) 160 return error; 161 162 ASN1_OCTET_STRING_Ptr attest_str(ASN1_OCTET_STRING_new()); 163 if (!attest_str.get() || 164 !ASN1_OCTET_STRING_set(attest_str.get(), attest_bytes.get(), attest_bytes_len)) 165 return TranslateLastOpenSslError(); 166 167 extension->reset( 168 X509_EXTENSION_create_by_OBJ(nullptr, oid.get(), 0 /* not critical */, attest_str.get())); 169 if (!extension->get()) 170 return TranslateLastOpenSslError(); 171 172 return KM_ERROR_OK; 173} 174 175static bool add_public_key(EVP_PKEY* key, X509* certificate, keymaster_error_t* error) { 176 if (!X509_set_pubkey(certificate, key)) { 177 *error = TranslateLastOpenSslError(); 178 return false; 179 } 180 return true; 181} 182 183static bool add_attestation_extension(const AuthorizationSet& attest_params, 184 const AuthorizationSet& tee_enforced, 185 const AuthorizationSet& sw_enforced, 186 const KeymasterContext& context, X509* certificate, 187 keymaster_error_t* error) { 188 X509_EXTENSION_Ptr attest_extension; 189 *error = build_attestation_extension(attest_params, tee_enforced, sw_enforced, context, 190 &attest_extension); 191 if (*error != KM_ERROR_OK) 192 return false; 193 194 if (!X509_add_ext(certificate, attest_extension.get() /* Don't release; copied */, 195 -1 /* insert at end */)) { 196 *error = TranslateLastOpenSslError(); 197 return false; 198 } 199 200 return true; 201} 202 203static keymaster_error_t get_certificate_blob(X509* certificate, keymaster_blob_t* blob) { 204 int len = i2d_X509(certificate, nullptr); 205 if (len < 0) 206 return TranslateLastOpenSslError(); 207 208 uint8_t* data = new uint8_t[len]; 209 if (!data) 210 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 211 212 uint8_t* p = data; 213 i2d_X509(certificate, &p); 214 215 blob->data_length = len; 216 blob->data = data; 217 218 return KM_ERROR_OK; 219} 220 221static bool allocate_cert_chain(size_t entry_count, keymaster_cert_chain_t* chain, 222 keymaster_error_t* error) { 223 if (chain->entries) { 224 for (size_t i = 0; i < chain->entry_count; ++i) 225 delete[] chain->entries[i].data; 226 delete[] chain->entries; 227 } 228 229 chain->entry_count = entry_count; 230 chain->entries = new keymaster_blob_t[entry_count]; 231 if (!chain->entries) { 232 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 233 return false; 234 } 235 return true; 236} 237 238// Copies the intermediate and root certificates into chain, leaving the first slot for the leaf 239// certificate. 240static bool copy_attestation_chain(const KeymasterContext& context, 241 keymaster_algorithm_t sign_algorithm, 242 keymaster_cert_chain_t* chain, keymaster_error_t* error) { 243 244 UniquePtr<keymaster_cert_chain_t, CertificateChainDelete> attest_key_chain( 245 context.AttestationChain(sign_algorithm, error)); 246 if (!attest_key_chain.get()) 247 return false; 248 249 if (!allocate_cert_chain(attest_key_chain->entry_count + 1, chain, error)) 250 return false; 251 252 chain->entries[0].data = nullptr; // Leave empty for the leaf certificate. 253 chain->entries[1].data_length = 0; 254 255 for (size_t i = 0; i < attest_key_chain->entry_count; ++i) { 256 chain->entries[i + 1] = attest_key_chain->entries[i]; 257 attest_key_chain->entries[i].data = nullptr; 258 } 259 260 return true; 261} 262 263keymaster_error_t AsymmetricKey::GenerateAttestation(const KeymasterContext& context, 264 const AuthorizationSet& attest_params, 265 const AuthorizationSet& tee_enforced, 266 const AuthorizationSet& sw_enforced, 267 keymaster_cert_chain_t* cert_chain) const { 268 269 keymaster_algorithm_t sign_algorithm; 270 if ((!sw_enforced.GetTagValue(TAG_ALGORITHM, &sign_algorithm) && 271 !tee_enforced.GetTagValue(TAG_ALGORITHM, &sign_algorithm))) 272 return KM_ERROR_UNKNOWN_ERROR; 273 274 if ((sign_algorithm != KM_ALGORITHM_RSA && sign_algorithm != KM_ALGORITHM_EC)) 275 return KM_ERROR_INCOMPATIBLE_ALGORITHM; 276 277 EVP_PKEY_Ptr pkey(EVP_PKEY_new()); 278 if (!InternalToEvp(pkey.get())) 279 return TranslateLastOpenSslError(); 280 281 X509_Ptr certificate(X509_new()); 282 if (!certificate.get()) 283 return TranslateLastOpenSslError(); 284 285 if (!X509_set_version(certificate.get(), 2 /* version 3, but zero-based */)) 286 return TranslateLastOpenSslError(); 287 288 ASN1_INTEGER_Ptr serialNumber(ASN1_INTEGER_new()); 289 if (!serialNumber.get() || !ASN1_INTEGER_set(serialNumber.get(), 1) || 290 !X509_set_serialNumber(certificate.get(), serialNumber.get() /* Don't release; copied */)) 291 return TranslateLastOpenSslError(); 292 293 // TODO(swillden): Find useful values (if possible) for issuerName and subjectName. 294 X509_NAME_Ptr issuerName(X509_NAME_new()); 295 if (!issuerName.get() || 296 !X509_NAME_add_entry_by_txt(issuerName.get(), "CN", MBSTRING_ASC, 297 reinterpret_cast<const uint8_t*>("Android Keymaster"), 298 -1 /* len */, -1 /* loc */, 0 /* set */) || 299 !X509_set_issuer_name(certificate.get(), issuerName.get() /* Don't release; copied */)) 300 return TranslateLastOpenSslError(); 301 302 X509_NAME_Ptr subjectName(X509_NAME_new()); 303 if (!subjectName.get() || 304 !X509_NAME_add_entry_by_txt(subjectName.get(), "CN", MBSTRING_ASC, 305 reinterpret_cast<const uint8_t*>("A Keymaster Key"), 306 -1 /* len */, -1 /* loc */, 0 /* set */) || 307 !X509_set_subject_name(certificate.get(), subjectName.get() /* Don't release; copied */)) 308 return TranslateLastOpenSslError(); 309 310 ASN1_TIME_Ptr notBefore(ASN1_TIME_new()); 311 uint64_t activeDateTime = 0; 312 authorizations().GetTagValue(TAG_ACTIVE_DATETIME, &activeDateTime); 313 if (!notBefore.get() || !ASN1_TIME_set(notBefore.get(), activeDateTime / 1000) || 314 !X509_set_notBefore(certificate.get(), notBefore.get() /* Don't release; copied */)) 315 return TranslateLastOpenSslError(); 316 317 ASN1_TIME_Ptr notAfter(ASN1_TIME_new()); 318 uint64_t usageExpireDateTime = UINT64_MAX; 319 authorizations().GetTagValue(TAG_USAGE_EXPIRE_DATETIME, &usageExpireDateTime); 320 // TODO(swillden): When trusty can use the C++ standard library change the calculation of 321 // notAfterTime to use std::numeric_limits<time_t>::max(), rather than assuming that time_t is 322 // 32 bits. 323 time_t notAfterTime = min(static_cast<uint64_t>(UINT32_MAX), usageExpireDateTime / 1000); 324 if (!notAfter.get() || !ASN1_TIME_set(notAfter.get(), notAfterTime) || 325 !X509_set_notAfter(certificate.get(), notAfter.get() /* Don't release; copied */)) 326 return TranslateLastOpenSslError(); 327 328 keymaster_error_t error = add_key_usage_extension(tee_enforced, sw_enforced, certificate.get()); 329 if (error != KM_ERROR_OK) { 330 return error; 331 } 332 333 EVP_PKEY_Ptr sign_key(context.AttestationKey(sign_algorithm, &error)); 334 335 if (!sign_key.get() || // 336 !add_public_key(pkey.get(), certificate.get(), &error) || 337 !add_attestation_extension(attest_params, tee_enforced, sw_enforced, context, 338 certificate.get(), &error)) 339 return error; 340 341 if (!copy_attestation_chain(context, sign_algorithm, cert_chain, &error)) 342 return error; 343 344 // Copy subject key identifier from cert_chain->entries[1] as authority key_id. 345 if (cert_chain->entry_count < 2) { 346 // cert_chain must have at least two entries, one for the cert we're trying to create and 347 // one for the cert for the key that signs the new cert. 348 return KM_ERROR_UNKNOWN_ERROR; 349 } 350 351 const uint8_t* p = cert_chain->entries[1].data; 352 X509_Ptr signing_cert(d2i_X509(nullptr, &p, cert_chain->entries[1].data_length)); 353 if (!signing_cert.get()) { 354 return TranslateLastOpenSslError(); 355 } 356 357 UniquePtr<X509V3_CTX> x509v3_ctx(new X509V3_CTX); 358 *x509v3_ctx = {}; 359 X509V3_set_ctx(x509v3_ctx.get(), signing_cert.get(), certificate.get(), nullptr /* req */, 360 nullptr /* crl */, 0 /* flags */); 361 362 X509_EXTENSION_Ptr auth_key_id(X509V3_EXT_nconf_nid(nullptr /* conf */, x509v3_ctx.get(), 363 NID_authority_key_identifier, 364 const_cast<char*>("keyid:always"))); 365 if (!auth_key_id.get() || 366 !X509_add_ext(certificate.get(), auth_key_id.get() /* Don't release; copied */, 367 -1 /* insert at end */)) { 368 return TranslateLastOpenSslError(); 369 } 370 371 if (!X509_sign(certificate.get(), sign_key.get(), EVP_sha256())) 372 return TranslateLastOpenSslError(); 373 374 return get_certificate_blob(certificate.get(), &cert_chain->entries[0]); 375} 376 377} // namespace keymaster 378