• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "openssl_utils.h"
18 
19 #include <keymaster/android_keymaster_utils.h>
20 
21 #include "openssl_err.h"
22 
23 namespace keymaster {
24 
ec_get_group_size(const EC_GROUP * group,size_t * key_size_bits)25 keymaster_error_t ec_get_group_size(const EC_GROUP* group, size_t* key_size_bits) {
26     switch (EC_GROUP_get_curve_name(group)) {
27     case NID_secp224r1:
28         *key_size_bits = 224;
29         break;
30     case NID_X9_62_prime256v1:
31         *key_size_bits = 256;
32         break;
33     case NID_secp384r1:
34         *key_size_bits = 384;
35         break;
36     case NID_secp521r1:
37         *key_size_bits = 521;
38         break;
39     default:
40         return KM_ERROR_UNSUPPORTED_EC_FIELD;
41     }
42     return KM_ERROR_OK;
43 }
44 
ec_get_group(keymaster_ec_curve_t curve)45 EC_GROUP* ec_get_group(keymaster_ec_curve_t curve) {
46     switch (curve) {
47     case KM_EC_CURVE_P_224:
48         return EC_GROUP_new_by_curve_name(NID_secp224r1);
49         break;
50     case KM_EC_CURVE_P_256:
51         return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
52         break;
53     case KM_EC_CURVE_P_384:
54         return EC_GROUP_new_by_curve_name(NID_secp384r1);
55         break;
56     case KM_EC_CURVE_P_521:
57         return EC_GROUP_new_by_curve_name(NID_secp521r1);
58         break;
59     default:
60         return nullptr;
61         break;
62     }
63 }
64 
convert_bn_to_blob(BIGNUM * bn,keymaster_blob_t * blob)65 void convert_bn_to_blob(BIGNUM* bn, keymaster_blob_t* blob) {
66     blob->data_length = BN_num_bytes(bn);
67     blob->data = new uint8_t[blob->data_length];
68     BN_bn2bin(bn, const_cast<uint8_t*>(blob->data));
69 }
70 
convert_to_evp(keymaster_algorithm_t algorithm)71 static int convert_to_evp(keymaster_algorithm_t algorithm) {
72     switch (algorithm) {
73     case KM_ALGORITHM_RSA:
74         return EVP_PKEY_RSA;
75     case KM_ALGORITHM_EC:
76         return EVP_PKEY_EC;
77     default:
78         return -1;
79     };
80 }
81 
convert_pkcs8_blob_to_evp(const uint8_t * key_data,size_t key_length,keymaster_algorithm_t expected_algorithm,UniquePtr<EVP_PKEY,EVP_PKEY_Delete> * pkey)82 keymaster_error_t convert_pkcs8_blob_to_evp(const uint8_t* key_data, size_t key_length,
83                                             keymaster_algorithm_t expected_algorithm,
84                                             UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) {
85     if (key_data == NULL || key_length <= 0)
86         return KM_ERROR_INVALID_KEY_BLOB;
87 
88     UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8(
89         d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, key_length));
90     if (pkcs8.get() == NULL)
91         return TranslateLastOpenSslError(true /* log_message */);
92 
93     pkey->reset(EVP_PKCS82PKEY(pkcs8.get()));
94     if (!pkey->get())
95         return TranslateLastOpenSslError(true /* log_message */);
96 
97     if (EVP_PKEY_type((*pkey)->type) != convert_to_evp(expected_algorithm)) {
98         LOG_E("EVP key algorithm was %d, not the expected %d", EVP_PKEY_type((*pkey)->type),
99               convert_to_evp(expected_algorithm));
100         return KM_ERROR_INVALID_KEY_BLOB;
101     }
102 
103     return KM_ERROR_OK;
104 }
105 
KeyMaterialToEvpKey(keymaster_key_format_t key_format,const KeymasterKeyBlob & key_material,keymaster_algorithm_t expected_algorithm,UniquePtr<EVP_PKEY,EVP_PKEY_Delete> * pkey)106 keymaster_error_t KeyMaterialToEvpKey(keymaster_key_format_t key_format,
107                                       const KeymasterKeyBlob& key_material,
108                                       keymaster_algorithm_t expected_algorithm,
109                                       UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) {
110     if (key_format != KM_KEY_FORMAT_PKCS8)
111         return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
112 
113     return convert_pkcs8_blob_to_evp(key_material.key_material, key_material.key_material_size,
114                                      expected_algorithm, pkey);
115 }
116 
EvpKeyToKeyMaterial(const EVP_PKEY * pkey,KeymasterKeyBlob * key_blob)117 keymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* pkey, KeymasterKeyBlob* key_blob) {
118     int key_data_size = i2d_PrivateKey(pkey, NULL /* key_data*/);
119     if (key_data_size <= 0)
120         return TranslateLastOpenSslError();
121 
122     if (!key_blob->Reset(key_data_size))
123         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
124 
125     uint8_t* tmp = key_blob->writable_data();
126     i2d_PrivateKey(pkey, &tmp);
127 
128     return KM_ERROR_OK;
129 }
130 
ec_group_size_bits(EC_KEY * ec_key)131 size_t ec_group_size_bits(EC_KEY* ec_key) {
132     const EC_GROUP* group = EC_KEY_get0_group(ec_key);
133     UniquePtr<BN_CTX, BN_CTX_Delete> bn_ctx(BN_CTX_new());
134     UniquePtr<BIGNUM, BIGNUM_Delete> order(BN_new());
135     if (!EC_GROUP_get_order(group, order.get(), bn_ctx.get())) {
136         LOG_E("Failed to get EC group order", 0);
137         return 0;
138     }
139     return BN_num_bits(order.get());
140 }
141 
142 }  // namespace keymaster
143