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 <keymaster/keymaster_configuration.h>
18
19 #include <stdio.h>
20 #include <memory>
21
22 #include <openssl/evp.h>
23 #include <openssl/x509.h>
24
25 #include "trusty_keymaster_device.h"
26
27 using keymaster::TrustyKeymasterDevice;
28
29 unsigned char rsa_privkey_pk8_der[] = {
30 0x30, 0x82, 0x02, 0x75, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
31 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x5f, 0x30, 0x82, 0x02, 0x5b, 0x02, 0x01,
32 0x00, 0x02, 0x81, 0x81, 0x00, 0xc6, 0x09, 0x54, 0x09, 0x04, 0x7d, 0x86, 0x34, 0x81, 0x2d, 0x5a,
33 0x21, 0x81, 0x76, 0xe4, 0x5c, 0x41, 0xd6, 0x0a, 0x75, 0xb1, 0x39, 0x01, 0xf2, 0x34, 0x22, 0x6c,
34 0xff, 0xe7, 0x76, 0x52, 0x1c, 0x5a, 0x77, 0xb9, 0xe3, 0x89, 0x41, 0x7b, 0x71, 0xc0, 0xb6, 0xa4,
35 0x4d, 0x13, 0xaf, 0xe4, 0xe4, 0xa2, 0x80, 0x5d, 0x46, 0xc9, 0xda, 0x29, 0x35, 0xad, 0xb1, 0xff,
36 0x0c, 0x1f, 0x24, 0xea, 0x06, 0xe6, 0x2b, 0x20, 0xd7, 0x76, 0x43, 0x0a, 0x4d, 0x43, 0x51, 0x57,
37 0x23, 0x3c, 0x6f, 0x91, 0x67, 0x83, 0xc3, 0x0e, 0x31, 0x0f, 0xcb, 0xd8, 0x9b, 0x85, 0xc2, 0xd5,
38 0x67, 0x71, 0x16, 0x97, 0x85, 0xac, 0x12, 0xbc, 0xa2, 0x44, 0xab, 0xda, 0x72, 0xbf, 0xb1, 0x9f,
39 0xc4, 0x4d, 0x27, 0xc8, 0x1e, 0x1d, 0x92, 0xde, 0x28, 0x4f, 0x40, 0x61, 0xed, 0xfd, 0x99, 0x28,
40 0x07, 0x45, 0xea, 0x6d, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x1b, 0xe0, 0xf0,
41 0x4d, 0x9c, 0xae, 0x37, 0x18, 0x69, 0x1f, 0x03, 0x53, 0x38, 0x30, 0x8e, 0x91, 0x56, 0x4b, 0x55,
42 0x89, 0x9f, 0xfb, 0x50, 0x84, 0xd2, 0x46, 0x0e, 0x66, 0x30, 0x25, 0x7e, 0x05, 0xb3, 0xce, 0xab,
43 0x02, 0x97, 0x2d, 0xfa, 0xbc, 0xd6, 0xce, 0x5f, 0x6e, 0xe2, 0x58, 0x9e, 0xb6, 0x79, 0x11, 0xed,
44 0x0f, 0xac, 0x16, 0xe4, 0x3a, 0x44, 0x4b, 0x8c, 0x86, 0x1e, 0x54, 0x4a, 0x05, 0x93, 0x36, 0x57,
45 0x72, 0xf8, 0xba, 0xf6, 0xb2, 0x2f, 0xc9, 0xe3, 0xc5, 0xf1, 0x02, 0x4b, 0x06, 0x3a, 0xc0, 0x80,
46 0xa7, 0xb2, 0x23, 0x4c, 0xf8, 0xae, 0xe8, 0xf6, 0xc4, 0x7b, 0xbf, 0x4f, 0xd3, 0xac, 0xe7, 0x24,
47 0x02, 0x90, 0xbe, 0xf1, 0x6c, 0x0b, 0x3f, 0x7f, 0x3c, 0xdd, 0x64, 0xce, 0x3a, 0xb5, 0x91, 0x2c,
48 0xf6, 0xe3, 0x2f, 0x39, 0xab, 0x18, 0x83, 0x58, 0xaf, 0xcc, 0xcd, 0x80, 0x81, 0x02, 0x41, 0x00,
49 0xe4, 0xb4, 0x9e, 0xf5, 0x0f, 0x76, 0x5d, 0x3b, 0x24, 0xdd, 0xe0, 0x1a, 0xce, 0xaa, 0xf1, 0x30,
50 0xf2, 0xc7, 0x66, 0x70, 0xa9, 0x1a, 0x61, 0xae, 0x08, 0xaf, 0x49, 0x7b, 0x4a, 0x82, 0xbe, 0x6d,
51 0xee, 0x8f, 0xcd, 0xd5, 0xe3, 0xf7, 0xba, 0x1c, 0xfb, 0x1f, 0x0c, 0x92, 0x6b, 0x88, 0xf8, 0x8c,
52 0x92, 0xbf, 0xab, 0x13, 0x7f, 0xba, 0x22, 0x85, 0x22, 0x7b, 0x83, 0xc3, 0x42, 0xff, 0x7c, 0x55,
53 0x02, 0x41, 0x00, 0xdd, 0xab, 0xb5, 0x83, 0x9c, 0x4c, 0x7f, 0x6b, 0xf3, 0xd4, 0x18, 0x32, 0x31,
54 0xf0, 0x05, 0xb3, 0x1a, 0xa5, 0x8a, 0xff, 0xdd, 0xa5, 0xc7, 0x9e, 0x4c, 0xce, 0x21, 0x7f, 0x6b,
55 0xc9, 0x30, 0xdb, 0xe5, 0x63, 0xd4, 0x80, 0x70, 0x6c, 0x24, 0xe9, 0xeb, 0xfc, 0xab, 0x28, 0xa6,
56 0xcd, 0xef, 0xd3, 0x24, 0xb7, 0x7e, 0x1b, 0xf7, 0x25, 0x1b, 0x70, 0x90, 0x92, 0xc2, 0x4f, 0xf5,
57 0x01, 0xfd, 0x91, 0x02, 0x40, 0x23, 0xd4, 0x34, 0x0e, 0xda, 0x34, 0x45, 0xd8, 0xcd, 0x26, 0xc1,
58 0x44, 0x11, 0xda, 0x6f, 0xdc, 0xa6, 0x3c, 0x1c, 0xcd, 0x4b, 0x80, 0xa9, 0x8a, 0xd5, 0x2b, 0x78,
59 0xcc, 0x8a, 0xd8, 0xbe, 0xb2, 0x84, 0x2c, 0x1d, 0x28, 0x04, 0x05, 0xbc, 0x2f, 0x6c, 0x1b, 0xea,
60 0x21, 0x4a, 0x1d, 0x74, 0x2a, 0xb9, 0x96, 0xb3, 0x5b, 0x63, 0xa8, 0x2a, 0x5e, 0x47, 0x0f, 0xa8,
61 0x8d, 0xbf, 0x82, 0x3c, 0xdd, 0x02, 0x40, 0x1b, 0x7b, 0x57, 0x44, 0x9a, 0xd3, 0x0d, 0x15, 0x18,
62 0x24, 0x9a, 0x5f, 0x56, 0xbb, 0x98, 0x29, 0x4d, 0x4b, 0x6a, 0xc1, 0x2f, 0xfc, 0x86, 0x94, 0x04,
63 0x97, 0xa5, 0xa5, 0x83, 0x7a, 0x6c, 0xf9, 0x46, 0x26, 0x2b, 0x49, 0x45, 0x26, 0xd3, 0x28, 0xc1,
64 0x1e, 0x11, 0x26, 0x38, 0x0f, 0xde, 0x04, 0xc2, 0x4f, 0x91, 0x6d, 0xec, 0x25, 0x08, 0x92, 0xdb,
65 0x09, 0xa6, 0xd7, 0x7c, 0xdb, 0xa3, 0x51, 0x02, 0x40, 0x77, 0x62, 0xcd, 0x8f, 0x4d, 0x05, 0x0d,
66 0xa5, 0x6b, 0xd5, 0x91, 0xad, 0xb5, 0x15, 0xd2, 0x4d, 0x7c, 0xcd, 0x32, 0xcc, 0xa0, 0xd0, 0x5f,
67 0x86, 0x6d, 0x58, 0x35, 0x14, 0xbd, 0x73, 0x24, 0xd5, 0xf3, 0x36, 0x45, 0xe8, 0xed, 0x8b, 0x4a,
68 0x1c, 0xb3, 0xcc, 0x4a, 0x1d, 0x67, 0x98, 0x73, 0x99, 0xf2, 0xa0, 0x9f, 0x5b, 0x3f, 0xb6, 0x8c,
69 0x88, 0xd5, 0xe5, 0xd9, 0x0a, 0xc3, 0x34, 0x92, 0xd6};
70 unsigned int rsa_privkey_pk8_der_len = 633;
71
72 unsigned char dsa_privkey_pk8_der[] = {
73 0x30, 0x82, 0x01, 0x4b, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x07, 0x2a, 0x86, 0x48,
74 0xce, 0x38, 0x04, 0x01, 0x30, 0x82, 0x01, 0x1e, 0x02, 0x81, 0x81, 0x00, 0xa3, 0xf3, 0xe9, 0xb6,
75 0x7e, 0x7d, 0x88, 0xf6, 0xb7, 0xe5, 0xf5, 0x1f, 0x3b, 0xee, 0xac, 0xd7, 0xad, 0xbc, 0xc9, 0xd1,
76 0x5a, 0xf8, 0x88, 0xc4, 0xef, 0x6e, 0x3d, 0x74, 0x19, 0x74, 0xe7, 0xd8, 0xe0, 0x26, 0x44, 0x19,
77 0x86, 0xaf, 0x19, 0xdb, 0x05, 0xe9, 0x3b, 0x8b, 0x58, 0x58, 0xde, 0xe5, 0x4f, 0x48, 0x15, 0x01,
78 0xea, 0xe6, 0x83, 0x52, 0xd7, 0xc1, 0x21, 0xdf, 0xb9, 0xb8, 0x07, 0x66, 0x50, 0xfb, 0x3a, 0x0c,
79 0xb3, 0x85, 0xee, 0xbb, 0x04, 0x5f, 0xc2, 0x6d, 0x6d, 0x95, 0xfa, 0x11, 0x93, 0x1e, 0x59, 0x5b,
80 0xb1, 0x45, 0x8d, 0xe0, 0x3d, 0x73, 0xaa, 0xf2, 0x41, 0x14, 0x51, 0x07, 0x72, 0x3d, 0xa2, 0xf7,
81 0x58, 0xcd, 0x11, 0xa1, 0x32, 0xcf, 0xda, 0x42, 0xb7, 0xcc, 0x32, 0x80, 0xdb, 0x87, 0x82, 0xec,
82 0x42, 0xdb, 0x5a, 0x55, 0x24, 0x24, 0xa2, 0xd1, 0x55, 0x29, 0xad, 0xeb, 0x02, 0x15, 0x00, 0xeb,
83 0xea, 0x17, 0xd2, 0x09, 0xb3, 0xd7, 0x21, 0x9a, 0x21, 0x07, 0x82, 0x8f, 0xab, 0xfe, 0x88, 0x71,
84 0x68, 0xf7, 0xe3, 0x02, 0x81, 0x80, 0x19, 0x1c, 0x71, 0xfd, 0xe0, 0x03, 0x0c, 0x43, 0xd9, 0x0b,
85 0xf6, 0xcd, 0xd6, 0xa9, 0x70, 0xe7, 0x37, 0x86, 0x3a, 0x78, 0xe9, 0xa7, 0x47, 0xa7, 0x47, 0x06,
86 0x88, 0xb1, 0xaf, 0xd7, 0xf3, 0xf1, 0xa1, 0xd7, 0x00, 0x61, 0x28, 0x88, 0x31, 0x48, 0x60, 0xd8,
87 0x11, 0xef, 0xa5, 0x24, 0x1a, 0x81, 0xc4, 0x2a, 0xe2, 0xea, 0x0e, 0x36, 0xd2, 0xd2, 0x05, 0x84,
88 0x37, 0xcf, 0x32, 0x7d, 0x09, 0xe6, 0x0f, 0x8b, 0x0c, 0xc8, 0xc2, 0xa4, 0xb1, 0xdc, 0x80, 0xca,
89 0x68, 0xdf, 0xaf, 0xd2, 0x90, 0xc0, 0x37, 0x58, 0x54, 0x36, 0x8f, 0x49, 0xb8, 0x62, 0x75, 0x8b,
90 0x48, 0x47, 0xc0, 0xbe, 0xf7, 0x9a, 0x92, 0xa6, 0x68, 0x05, 0xda, 0x9d, 0xaf, 0x72, 0x9a, 0x67,
91 0xb3, 0xb4, 0x14, 0x03, 0xae, 0x4f, 0x4c, 0x76, 0xb9, 0xd8, 0x64, 0x0a, 0xba, 0x3b, 0xa8, 0x00,
92 0x60, 0x4d, 0xae, 0x81, 0xc3, 0xc5, 0x04, 0x17, 0x02, 0x15, 0x00, 0x81, 0x9d, 0xfd, 0x53, 0x0c,
93 0xc1, 0x8f, 0xbe, 0x8b, 0xea, 0x00, 0x26, 0x19, 0x29, 0x33, 0x91, 0x84, 0xbe, 0xad, 0x81};
94 unsigned int dsa_privkey_pk8_der_len = 335;
95
96 unsigned char ec_privkey_pk8_der[] = {
97 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
98 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02,
99 0x01, 0x01, 0x04, 0x20, 0x73, 0x7c, 0x2e, 0xcd, 0x7b, 0x8d, 0x19, 0x40, 0xbf, 0x29, 0x30, 0xaa,
100 0x9b, 0x4e, 0xd3, 0xff, 0x94, 0x1e, 0xed, 0x09, 0x36, 0x6b, 0xc0, 0x32, 0x99, 0x98, 0x64, 0x81,
101 0xf3, 0xa4, 0xd8, 0x59, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xbf, 0x85, 0xd7, 0x72, 0x0d, 0x07,
102 0xc2, 0x54, 0x61, 0x68, 0x3b, 0xc6, 0x48, 0xb4, 0x77, 0x8a, 0x9a, 0x14, 0xdd, 0x8a, 0x02, 0x4e,
103 0x3b, 0xdd, 0x8c, 0x7d, 0xdd, 0x9a, 0xb2, 0xb5, 0x28, 0xbb, 0xc7, 0xaa, 0x1b, 0x51, 0xf1, 0x4e,
104 0xbb, 0xbb, 0x0b, 0xd0, 0xce, 0x21, 0xbc, 0xc4, 0x1c, 0x6e, 0xb0, 0x00, 0x83, 0xcf, 0x33, 0x76,
105 0xd1, 0x1f, 0xd4, 0x49, 0x49, 0xe0, 0xb2, 0x18, 0x3b, 0xfe};
106 unsigned int ec_privkey_pk8_der_len = 138;
107
108 keymaster_key_param_t ec_params[] = {
109 keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC),
110 keymaster_param_long(KM_TAG_EC_CURVE, KM_EC_CURVE_P_521),
111 keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN),
112 keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_VERIFY),
113 keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
114 keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED),
115 };
116 keymaster_key_param_set_t ec_param_set = {ec_params, sizeof(ec_params) / sizeof(*ec_params)};
117
118 keymaster_key_param_t rsa_params[] = {
119 keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA),
120 keymaster_param_int(KM_TAG_KEY_SIZE, 1024),
121 keymaster_param_long(KM_TAG_RSA_PUBLIC_EXPONENT, 65537),
122 keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN),
123 keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_VERIFY),
124 keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
125 keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
126 keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED),
127 };
128 keymaster_key_param_set_t rsa_param_set = {rsa_params, sizeof(rsa_params) / sizeof(*rsa_params)};
129
130 struct EVP_PKEY_Delete {
operator ()EVP_PKEY_Delete131 void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
132 };
133
134 struct EVP_PKEY_CTX_Delete {
operator ()EVP_PKEY_CTX_Delete135 void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
136 };
137
do_operation(TrustyKeymasterDevice * device,keymaster_purpose_t purpose,keymaster_key_blob_t * key,keymaster_blob_t * input,keymaster_blob_t * signature,keymaster_blob_t * output)138 static bool do_operation(TrustyKeymasterDevice* device, keymaster_purpose_t purpose,
139 keymaster_key_blob_t* key, keymaster_blob_t* input,
140 keymaster_blob_t* signature, keymaster_blob_t* output) {
141 keymaster_key_param_t params[] = {
142 keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
143 keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
144 };
145 keymaster_key_param_set_t param_set = {params, sizeof(params) / sizeof(*params)};
146 keymaster_operation_handle_t op_handle;
147 keymaster_error_t error = device->begin(purpose, key, ¶m_set, nullptr, &op_handle);
148 if (error != KM_ERROR_OK) {
149 printf("Keymaster begin() failed: %d\n", error);
150 return false;
151 }
152 size_t input_consumed;
153 error = device->update(op_handle, nullptr, input, &input_consumed, nullptr, nullptr);
154 if (error != KM_ERROR_OK) {
155 printf("Keymaster update() failed: %d\n", error);
156 return false;
157 }
158 if (input_consumed != input->data_length) {
159 // This should never happen. If it does, it's a bug in the keymaster implementation.
160 printf("Keymaster update() did not consume all data.\n");
161 device->abort(op_handle);
162 return false;
163 }
164 error = device->finish(op_handle, nullptr, nullptr, signature, nullptr, output);
165 if (error != KM_ERROR_OK) {
166 printf("Keymaster finish() failed: %d\n", error);
167 return false;
168 }
169 return true;
170 }
171
test_import_rsa(TrustyKeymasterDevice * device)172 static bool test_import_rsa(TrustyKeymasterDevice* device) {
173 printf("===================\n");
174 printf("= RSA Import Test =\n");
175 printf("===================\n\n");
176
177 printf("=== Importing RSA keypair === \n");
178 keymaster_key_blob_t key;
179 keymaster_blob_t private_key = {rsa_privkey_pk8_der, rsa_privkey_pk8_der_len};
180 int error = device->import_key(&rsa_param_set, KM_KEY_FORMAT_PKCS8, &private_key, &key, nullptr);
181 if (error != KM_ERROR_OK) {
182 printf("Error importing RSA key: %d\n\n", error);
183 return false;
184 }
185 std::unique_ptr<const uint8_t[]> key_deleter(key.key_material);
186
187 printf("=== Signing with imported RSA key ===\n");
188 size_t message_len = 1024 / 8;
189 std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
190 memset(message.get(), 'a', message_len);
191 keymaster_blob_t input = {message.get(), message_len}, signature;
192
193 if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
194 printf("Error signing data with imported RSA key\n\n");
195 return false;
196 }
197 std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
198
199 printf("=== Verifying with imported RSA key === \n");
200 if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
201 printf("Error verifying data with imported RSA key\n\n");
202 return false;
203 }
204
205 printf("\n");
206 return true;
207 }
208
test_rsa(TrustyKeymasterDevice * device)209 static bool test_rsa(TrustyKeymasterDevice* device) {
210 printf("============\n");
211 printf("= RSA Test =\n");
212 printf("============\n\n");
213
214 printf("=== Generating RSA key pair ===\n");
215 keymaster_key_blob_t key;
216 int error = device->generate_key(&rsa_param_set, &key, nullptr);
217 if (error != KM_ERROR_OK) {
218 printf("Error generating RSA key pair: %d\n\n", error);
219 return false;
220 }
221 std::unique_ptr<const uint8_t[]> key_deleter(key.key_material);
222
223 printf("=== Signing with RSA key === \n");
224 size_t message_len = 1024 / 8;
225 std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
226 memset(message.get(), 'a', message_len);
227 keymaster_blob_t input = {message.get(), message_len}, signature;
228
229 if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
230 printf("Error signing data with RSA key\n\n");
231 return false;
232 }
233 std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
234
235 printf("=== Verifying with RSA key === \n");
236 if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
237 printf("Error verifying data with RSA key\n\n");
238 return false;
239 }
240
241 printf("=== Exporting RSA public key ===\n");
242 keymaster_blob_t exported_key;
243 error = device->export_key(KM_KEY_FORMAT_X509, &key, nullptr, nullptr, &exported_key);
244 if (error != KM_ERROR_OK) {
245 printf("Error exporting RSA public key: %d\n\n", error);
246 return false;
247 }
248
249 printf("=== Verifying with exported key ===\n");
250 const uint8_t* tmp = exported_key.data;
251 std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
252 d2i_PUBKEY(NULL, &tmp, exported_key.data_length));
253 std::unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(EVP_PKEY_CTX_new(pkey.get(), NULL));
254 if (EVP_PKEY_verify_init(ctx.get()) != 1) {
255 printf("Error initializing openss EVP context\n\n");
256 return false;
257 }
258 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
259 printf("Exported key was the wrong type?!?\n\n");
260 return false;
261 }
262
263 EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING);
264 if (EVP_PKEY_verify(ctx.get(), signature.data, signature.data_length, message.get(),
265 message_len) != 1) {
266 printf("Verification with exported pubkey failed.\n\n");
267 return false;
268 } else {
269 printf("Verification succeeded\n");
270 }
271
272 printf("\n");
273 return true;
274 }
275
test_import_ecdsa(TrustyKeymasterDevice * device)276 static bool test_import_ecdsa(TrustyKeymasterDevice* device) {
277 printf("=====================\n");
278 printf("= ECDSA Import Test =\n");
279 printf("=====================\n\n");
280
281 printf("=== Importing ECDSA keypair === \n");
282 keymaster_key_blob_t key;
283 keymaster_blob_t private_key = {ec_privkey_pk8_der, ec_privkey_pk8_der_len};
284 int error = device->import_key(&ec_param_set, KM_KEY_FORMAT_PKCS8, &private_key, &key, nullptr);
285 if (error != KM_ERROR_OK) {
286 printf("Error importing ECDSA key: %d\n\n", error);
287 return false;
288 }
289 std::unique_ptr<const uint8_t[]> deleter(key.key_material);
290
291 printf("=== Signing with imported ECDSA key ===\n");
292 keymaster_ec_sign_params_t sign_params = {DIGEST_NONE};
293 size_t message_len = 30 /* arbitrary */;
294 std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
295 memset(message.get(), 'a', message_len);
296 keymaster_blob_t input = {message.get(), message_len}, signature;
297
298 if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
299 printf("Error signing data with imported ECDSA key\n\n");
300 return false;
301 }
302 std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
303
304 printf("=== Verifying with imported ECDSA key === \n");
305 if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
306 printf("Error verifying data with imported ECDSA key\n\n");
307 return false;
308 }
309
310 printf("\n");
311 return true;
312 }
313
test_ecdsa(TrustyKeymasterDevice * device)314 static bool test_ecdsa(TrustyKeymasterDevice* device) {
315 printf("==============\n");
316 printf("= ECDSA Test =\n");
317 printf("==============\n\n");
318
319 printf("=== Generating ECDSA key pair ===\n");
320 keymaster_key_blob_t key;
321 int error = device->generate_key(&ec_param_set, &key, nullptr);
322 if (error != KM_ERROR_OK) {
323 printf("Error generating ECDSA key pair: %d\n\n", error);
324 return false;
325 }
326 std::unique_ptr<const uint8_t[]> key_deleter(key.key_material);
327
328 printf("=== Signing with ECDSA key === \n");
329 size_t message_len = 30 /* arbitrary */;
330 std::unique_ptr<uint8_t[]> message(new uint8_t[message_len]);
331 memset(message.get(), 'a', message_len);
332 keymaster_blob_t input = {message.get(), message_len}, signature;
333
334 if (!do_operation(device, KM_PURPOSE_SIGN, &key, &input, nullptr, &signature)) {
335 printf("Error signing data with ECDSA key\n\n");
336 return false;
337 }
338 std::unique_ptr<const uint8_t[]> signature_deleter(signature.data);
339
340 printf("=== Verifying with ECDSA key === \n");
341 if (!do_operation(device, KM_PURPOSE_VERIFY, &key, &input, &signature, nullptr)) {
342 printf("Error verifying data with ECDSA key\n\n");
343 return false;
344 }
345
346 printf("=== Exporting ECDSA public key ===\n");
347 keymaster_blob_t exported_key;
348 error = device->export_key(KM_KEY_FORMAT_X509, &key, nullptr, nullptr, &exported_key);
349 if (error != KM_ERROR_OK) {
350 printf("Error exporting ECDSA public key: %d\n\n", error);
351 return false;
352 }
353
354 printf("=== Verifying with exported key ===\n");
355 const uint8_t* tmp = exported_key.data;
356 std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
357 d2i_PUBKEY(NULL, &tmp, exported_key.data_length));
358 std::unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(EVP_PKEY_CTX_new(pkey.get(), NULL));
359 if (EVP_PKEY_verify_init(ctx.get()) != 1) {
360 printf("Error initializing openssl EVP context\n\n");
361 return false;
362 }
363 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
364 printf("Exported key was the wrong type?!?\n\n");
365 return false;
366 }
367
368 if (EVP_PKEY_verify(ctx.get(), signature.data, signature.data_length, message.get(),
369 message_len) != 1) {
370 printf("Verification with exported pubkey failed.\n\n");
371 return false;
372 } else {
373 printf("Verification succeeded\n");
374 }
375
376 printf("\n");
377 return true;
378 }
379
main(void)380 int main(void) {
381 TrustyKeymasterDevice device(NULL);
382 keymaster::ConfigureDevice(reinterpret_cast<keymaster2_device_t*>(&device));
383 if (device.session_error() != KM_ERROR_OK) {
384 printf("Failed to initialize Trusty session: %d\n", device.session_error());
385 return 1;
386 }
387 printf("Trusty session initialized\n");
388
389 bool success = true;
390 success &= test_rsa(&device);
391 success &= test_import_rsa(&device);
392 success &= test_ecdsa(&device);
393 success &= test_import_ecdsa(&device);
394
395 if (success) {
396 printf("\nTESTS PASSED!\n");
397 } else {
398 printf("\n!!!!TESTS FAILED!!!\n");
399 }
400
401 return success ? 0 : 1;
402 }
403