14d306ec792b4348253aa77dff965bff5def1dccbShawn Willden/*
24d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * Copyright 2015 The Android Open Source Project
34d306ec792b4348253aa77dff965bff5def1dccbShawn Willden *
44d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * Licensed under the Apache License, Version 2.0 (the "License");
54d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * you may not use this file except in compliance with the License.
64d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * You may obtain a copy of the License at
74d306ec792b4348253aa77dff965bff5def1dccbShawn Willden *
84d306ec792b4348253aa77dff965bff5def1dccbShawn Willden *      http://www.apache.org/licenses/LICENSE-2.0
94d306ec792b4348253aa77dff965bff5def1dccbShawn Willden *
104d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * Unless required by applicable law or agreed to in writing, software
114d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * distributed under the License is distributed on an "AS IS" BASIS,
124d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * See the License for the specific language governing permissions and
144d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * limitations under the License.
154d306ec792b4348253aa77dff965bff5def1dccbShawn Willden */
164d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
174d306ec792b4348253aa77dff965bff5def1dccbShawn Willden#include "openssl_utils.h"
184d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
19398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden#include <keymaster/android_keymaster_utils.h>
20398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden
214d306ec792b4348253aa77dff965bff5def1dccbShawn Willden#include "openssl_err.h"
224d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
234d306ec792b4348253aa77dff965bff5def1dccbShawn Willdennamespace keymaster {
244d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
25fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duongkeymaster_error_t ec_get_group_size(const EC_GROUP* group, size_t* key_size_bits) {
26fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    switch (EC_GROUP_get_curve_name(group)) {
27fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case NID_secp224r1:
28fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        *key_size_bits = 224;
29fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
30fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case NID_X9_62_prime256v1:
31fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        *key_size_bits = 256;
32fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
33fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case NID_secp384r1:
34fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        *key_size_bits = 384;
35fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
36fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case NID_secp521r1:
37fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        *key_size_bits = 521;
38fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
39fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    default:
40fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        return KM_ERROR_UNSUPPORTED_EC_FIELD;
41fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    }
42fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    return KM_ERROR_OK;
43fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong}
44fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong
45fabacaf3e6019804cc8a98a2b8296be1d0125519Thai DuongEC_GROUP* ec_get_group(keymaster_ec_curve_t curve) {
46fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    switch (curve) {
47fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case KM_EC_CURVE_P_224:
48fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        return EC_GROUP_new_by_curve_name(NID_secp224r1);
49fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
50fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case KM_EC_CURVE_P_256:
51fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
52fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
53fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case KM_EC_CURVE_P_384:
54fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        return EC_GROUP_new_by_curve_name(NID_secp384r1);
55fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
56fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    case KM_EC_CURVE_P_521:
57fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        return EC_GROUP_new_by_curve_name(NID_secp521r1);
58fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
59fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    default:
60fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        return nullptr;
61fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong        break;
62fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    }
63fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong}
64fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong
654d306ec792b4348253aa77dff965bff5def1dccbShawn Willdenstatic int convert_to_evp(keymaster_algorithm_t algorithm) {
664d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    switch (algorithm) {
674d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    case KM_ALGORITHM_RSA:
684d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        return EVP_PKEY_RSA;
699c65b2bd1978a918b52a459596dafc7dde992416Shawn Willden    case KM_ALGORITHM_EC:
704d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        return EVP_PKEY_EC;
714d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    default:
724d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        return -1;
734d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    };
744d306ec792b4348253aa77dff965bff5def1dccbShawn Willden}
754d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
764d306ec792b4348253aa77dff965bff5def1dccbShawn Willdenkeymaster_error_t convert_pkcs8_blob_to_evp(const uint8_t* key_data, size_t key_length,
774d306ec792b4348253aa77dff965bff5def1dccbShawn Willden                                            keymaster_algorithm_t expected_algorithm,
784d306ec792b4348253aa77dff965bff5def1dccbShawn Willden                                            UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) {
794d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    if (key_data == NULL || key_length <= 0)
804d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        return KM_ERROR_INVALID_KEY_BLOB;
814d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
824d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8(
834d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, key_length));
844d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    if (pkcs8.get() == NULL)
854d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        return TranslateLastOpenSslError(true /* log_message */);
864d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
874d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    pkey->reset(EVP_PKCS82PKEY(pkcs8.get()));
884d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    if (!pkey->get())
894d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        return TranslateLastOpenSslError(true /* log_message */);
904d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
914d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    if (EVP_PKEY_type((*pkey)->type) != convert_to_evp(expected_algorithm)) {
924d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        LOG_E("EVP key algorithm was %d, not the expected %d", EVP_PKEY_type((*pkey)->type),
934d306ec792b4348253aa77dff965bff5def1dccbShawn Willden              convert_to_evp(expected_algorithm));
944d306ec792b4348253aa77dff965bff5def1dccbShawn Willden        return KM_ERROR_INVALID_KEY_BLOB;
954d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    }
964d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
974d306ec792b4348253aa77dff965bff5def1dccbShawn Willden    return KM_ERROR_OK;
984d306ec792b4348253aa77dff965bff5def1dccbShawn Willden}
994d306ec792b4348253aa77dff965bff5def1dccbShawn Willden
100398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willdenkeymaster_error_t KeyMaterialToEvpKey(keymaster_key_format_t key_format,
101398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden                                      const KeymasterKeyBlob& key_material,
102398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden                                      keymaster_algorithm_t expected_algorithm,
103398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden                                      UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) {
104398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden    if (key_format != KM_KEY_FORMAT_PKCS8)
105398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden        return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
106398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden
107398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden    return convert_pkcs8_blob_to_evp(key_material.key_material, key_material.key_material_size,
108398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden                                     expected_algorithm, pkey);
109398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden}
110398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden
111398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willdenkeymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* pkey, KeymasterKeyBlob* key_blob) {
112398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden    int key_data_size = i2d_PrivateKey(pkey, NULL /* key_data*/);
113398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden    if (key_data_size <= 0)
114398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden        return TranslateLastOpenSslError();
115398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden
1160f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden    if (!key_blob->Reset(key_data_size))
117398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
118398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden
119398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden    uint8_t* tmp = key_blob->writable_data();
120398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden    i2d_PrivateKey(pkey, &tmp);
121398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden
122398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden    return KM_ERROR_OK;
123398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden}
124398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden
125d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdensize_t ec_group_size_bits(EC_KEY* ec_key) {
126d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    const EC_GROUP* group = EC_KEY_get0_group(ec_key);
127d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    UniquePtr<BN_CTX, BN_CTX_Delete> bn_ctx(BN_CTX_new());
128d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    UniquePtr<BIGNUM, BIGNUM_Delete> order(BN_new());
129d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    if (!EC_GROUP_get_order(group, order.get(), bn_ctx.get())) {
130d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        LOG_E("Failed to get EC group order", 0);
131d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        return 0;
132d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    }
133d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    return BN_num_bits(order.get());
134d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}
135d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
1364d306ec792b4348253aa77dff965bff5def1dccbShawn Willden}  // namespace keymaster
137