• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 "export_key.h"
18 #include "proto_utils.h"
19 
20 #include <android-base/logging.h>
21 
22 #include <openssl/bn.h>
23 #include <openssl/bytestring.h>
24 #include <openssl/ec.h>
25 #include <openssl/evp.h>
26 #include <openssl/rsa.h>
27 
28 namespace android {
29 namespace hardware {
30 namespace keymaster {
31 
32 // HAL
33 using ::android::hardware::keymaster::V4_0::Algorithm;
34 using ::android::hardware::keymaster::V4_0::EcCurve;
35 using ::android::hardware::keymaster::V4_0::KeyFormat;
36 using ::android::hardware::keymaster::V4_0::Tag;
37 using ::android::hardware::keymaster::V4_0::TagType;
38 
39 // App
40 namespace nosapp = nugget::app::keymaster;
41 
42 // BoringSSL
43 using bssl::UniquePtr;
44 
45 // std
46 using std::unique_ptr;
47 
export_key_der(const ExportKeyResponse & response,hidl_vec<uint8_t> * der)48 ErrorCode export_key_der(const ExportKeyResponse& response,
49                           hidl_vec<uint8_t> *der) {
50 
51   if (response.algorithm() == nosapp::Algorithm::RSA) {
52       bssl::UniquePtr<BIGNUM> n(BN_new());
53       BN_le2bn(
54           reinterpret_cast<const uint8_t *>(response.rsa().n().data()),
55           response.rsa().n().size(), n.get());
56 
57       bssl::UniquePtr<BIGNUM> e(BN_new());
58       if (!BN_set_word(e.get(), response.rsa().e())) {
59           LOG(ERROR) << "ExportKey: BN_set_word failed";
60           return ErrorCode::UNKNOWN_ERROR;
61       }
62 
63       bssl::UniquePtr<RSA> rsa(RSA_new());
64       if (!RSA_set0_key(rsa.get(), n.get(), e.get(), NULL)) {
65           LOG(ERROR) << "ExportKey: RSA_set0_key failed";
66           return ErrorCode::UNKNOWN_ERROR;
67       }
68 
69       CBB cbb;
70       uint8_t *data = new uint8_t[1024];  /* Plenty for RSA 4-k. */
71       CBB_init_fixed(&cbb, data, 1024);
72       bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
73       EVP_PKEY_set1_RSA(pkey.get(), rsa.get());
74       if (!EVP_marshal_public_key(&cbb, pkey.get())) {
75           LOG(ERROR) << "ExportKey: EVP_marshal_public_key failed";
76           return ErrorCode::UNKNOWN_ERROR;
77       }
78 
79       der->setToExternal(
80           const_cast<uint8_t*>(
81               data), CBB_len(&cbb), true /* Transfer ownership. */);
82       CBB_cleanup(&cbb);
83   } else {
84       EcCurve ec_curve;
85       /* TODO: eliminate this type-cast. */
86       if (translate_ec_curve(
87               (nosapp::EcCurve)response.ec().curve_id(),
88               &ec_curve) != ErrorCode::OK) {
89           LOG(ERROR) << "Failed to parse response device ec curve_id: "
90                      << response.ec().curve_id();
91           return ErrorCode::UNKNOWN_ERROR;
92       }
93     int curve_nid;
94     switch (ec_curve) {
95     case EcCurve::P_224:
96         curve_nid = NID_secp224r1;
97         break;
98     case EcCurve::P_256:
99         curve_nid = NID_X9_62_prime256v1;
100         break;
101     case EcCurve::P_384:
102         curve_nid = NID_secp384r1;
103         break;
104     case EcCurve::P_521:
105         curve_nid = NID_secp521r1;
106         break;
107     default:
108         LOG(ERROR) << "ExportKey: received invalid EcCurve id: "
109                    << (uint32_t) ec_curve;
110         return ErrorCode::UNKNOWN_ERROR;
111     }
112 
113     bssl::UniquePtr<EC_GROUP> ec_group(EC_GROUP_new_by_curve_name(curve_nid));
114     if (!ec_group.get()) {
115         LOG(ERROR) << "EC_GROUP_new_by_name("
116                    << (uint32_t)curve_nid << ") failed";
117         return ErrorCode::UNKNOWN_ERROR;
118     }
119     bssl::UniquePtr<EC_POINT> ec_point(EC_POINT_new(ec_group.get()));
120     if (!ec_point.get()) {
121         LOG(ERROR) << "EC_POINT_new() failed";
122         return ErrorCode::UNKNOWN_ERROR;
123     }
124     bssl::UniquePtr<BIGNUM> x(BN_new());
125     BN_le2bn(
126         reinterpret_cast<const uint8_t *>(response.ec().x().data()),
127         response.ec().x().size(), x.get());
128     bssl::UniquePtr<BIGNUM> y(BN_new());
129     BN_le2bn(
130         reinterpret_cast<const uint8_t *>(response.ec().y().data()),
131         response.ec().y().size(), y.get());
132     if (!EC_POINT_set_affine_coordinates_GFp(
133             ec_group.get(), ec_point.get(), x.get(), y.get(), NULL)) {
134         LOG(ERROR) << "EC_POINT_set_affine_coordinates() failed";
135         return ErrorCode::UNKNOWN_ERROR;
136     }
137 
138     bssl::UniquePtr<EC_KEY> ec_key(EC_KEY_new_by_curve_name(curve_nid));
139     if (!ec_key.get()) {
140         LOG(ERROR) << "EC_KEY_new() failed";
141         return ErrorCode::UNKNOWN_ERROR;
142     }
143 
144     if (!EC_KEY_set_public_key(ec_key.get(), ec_point.get())) {
145         LOG(ERROR) << "EC_KEY_set_public_key() failed";
146         return ErrorCode::UNKNOWN_ERROR;
147     }
148 
149     bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
150     if (!pkey.get()) {
151         LOG(ERROR) << "EVP_PKEY_new() failed";
152         return ErrorCode::UNKNOWN_ERROR;
153     }
154     if (!EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get())) {
155         LOG(ERROR) << "EVP_PKEY_set1_EC_KEY() failed";
156         return ErrorCode::UNKNOWN_ERROR;
157     }
158     CBB cbb;
159     uint8_t *data = new uint8_t[256];  /* Plenty for EC-521. */
160     CBB_init_fixed(&cbb, data, 256);
161     if (!EVP_marshal_public_key(&cbb, pkey.get())) {
162       LOG(ERROR) << "ExportKey: EVP_marshal_public_key failed";
163       return ErrorCode::UNKNOWN_ERROR;
164     }
165 
166     der->setToExternal(
167             const_cast<uint8_t*>(
168                 data), CBB_len(&cbb), true /* Transfer ownership. */);
169     CBB_cleanup(&cbb);
170   }
171 
172   return ErrorCode::OK;
173 }
174 
175 }  // namespace keymaster
176 }  // hardware
177 }  // android
178