1 /*
2 * Copyright 2017 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 "atap_ops.h"
18 #include "atap_util.h"
19 #include "libatap.h"
20
21 static uint8_t session_shared_secret[ATAP_ECDH_SHARED_SECRET_LEN];
22 static uint8_t session_key[ATAP_AES_128_KEY_LEN];
23 static AtapOperation operation;
24
auth_key_signature_generate(AtapOps * ops,uint8_t device_pubkey[ATAP_ECDH_KEY_LEN],uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN],uint8_t ** signature,uint32_t * signature_len)25 static AtapResult auth_key_signature_generate(
26 AtapOps* ops,
27 uint8_t device_pubkey[ATAP_ECDH_KEY_LEN],
28 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN],
29 uint8_t** signature,
30 uint32_t* signature_len) {
31 AtapResult ret = 0;
32 uint8_t nonce[ATAP_NONCE_LEN];
33 *signature = (uint8_t*)atap_malloc(ATAP_SIGNATURE_LEN_MAX);
34 if (*signature == NULL) {
35 return ATAP_RESULT_ERROR_OOM;
36 }
37 /* deriving nonce uses same HKDF as deriving session key */
38 ret = derive_session_key(ops,
39 device_pubkey,
40 ca_pubkey,
41 session_shared_secret,
42 "SIGN",
43 nonce,
44 ATAP_NONCE_LEN);
45 if (ret != ATAP_RESULT_OK) {
46 return ret;
47 }
48 return ops->auth_key_sign(
49 ops, nonce, ATAP_NONCE_LEN, *signature, signature_len);
50 }
51
read_available_public_keys(AtapOps * ops,AtapInnerCaRequest * inner_ca_request)52 static AtapResult read_available_public_keys(
53 AtapOps* ops, AtapInnerCaRequest* inner_ca_request) {
54 AtapResult ret = 0;
55
56 inner_ca_request->RSA_pubkey.data = (uint8_t*)atap_malloc(ATAP_KEY_LEN_MAX);
57 inner_ca_request->RSA_pubkey.data_length = ATAP_KEY_LEN_MAX;
58 inner_ca_request->ECDSA_pubkey.data = (uint8_t*)atap_malloc(ATAP_KEY_LEN_MAX);
59 inner_ca_request->ECDSA_pubkey.data_length = ATAP_KEY_LEN_MAX;
60 inner_ca_request->edDSA_pubkey.data = (uint8_t*)atap_malloc(ATAP_KEY_LEN_MAX);
61 inner_ca_request->edDSA_pubkey.data_length = ATAP_KEY_LEN_MAX;
62
63 if (inner_ca_request->RSA_pubkey.data == NULL ||
64 inner_ca_request->ECDSA_pubkey.data == NULL ||
65 inner_ca_request->edDSA_pubkey.data == NULL) {
66 return ATAP_RESULT_ERROR_OOM;
67 }
68 ret = ops->read_attestation_public_key(
69 ops,
70 ATAP_KEY_TYPE_RSA,
71 inner_ca_request->RSA_pubkey.data,
72 &inner_ca_request->RSA_pubkey.data_length);
73 if (ret != ATAP_RESULT_OK) {
74 return ret;
75 }
76 ret = ops->read_attestation_public_key(
77 ops,
78 ATAP_KEY_TYPE_ECDSA,
79 inner_ca_request->ECDSA_pubkey.data,
80 &inner_ca_request->ECDSA_pubkey.data_length);
81 if (ret != ATAP_RESULT_OK) {
82 return ret;
83 }
84 ret = ops->read_attestation_public_key(
85 ops,
86 ATAP_KEY_TYPE_edDSA,
87 inner_ca_request->edDSA_pubkey.data,
88 &inner_ca_request->edDSA_pubkey.data_length);
89 /* edDSA support is not required in the initial version */
90 if (ret == ATAP_RESULT_ERROR_UNSUPPORTED_OPERATION) {
91 atap_free(inner_ca_request->edDSA_pubkey.data);
92 inner_ca_request->edDSA_pubkey.data = NULL;
93 inner_ca_request->edDSA_pubkey.data_length = 0;
94 ret = ATAP_RESULT_OK;
95 }
96 return ret;
97 }
98
initialize_session(AtapOps * ops,const uint8_t * operation_start,uint32_t operation_start_size,AtapKeyType * auth_key_type,uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN],AtapCaRequest * ca_request,AtapInnerCaRequest * inner_ca_request)99 static AtapResult initialize_session(AtapOps* ops,
100 const uint8_t* operation_start,
101 uint32_t operation_start_size,
102 AtapKeyType* auth_key_type,
103 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN],
104 AtapCaRequest* ca_request,
105 AtapInnerCaRequest* inner_ca_request) {
106 uint32_t message_length = 0;
107 AtapCurveType curve_type = 0;
108 AtapResult ret = 0;
109 uint8_t* buf_ptr = (uint8_t*)operation_start + 4;
110
111 atap_memset(ca_request, 0, sizeof(AtapCaRequest));
112 atap_memset(inner_ca_request, 0, sizeof(AtapInnerCaRequest));
113
114 if (operation_start_size != ATAP_OPERATION_START_LEN) {
115 return ATAP_RESULT_ERROR_INVALID_INPUT;
116 }
117 if (operation_start[0] != ATAP_PROTOCOL_VERSION) {
118 return ATAP_RESULT_ERROR_INVALID_INPUT;
119 }
120 copy_uint32_from_buf(&buf_ptr, &message_length);
121 if (message_length != ATAP_ECDH_KEY_LEN + 2) {
122 return ATAP_RESULT_ERROR_INVALID_INPUT;
123 }
124 curve_type = operation_start[ATAP_HEADER_LEN];
125 operation = operation_start[ATAP_HEADER_LEN + 1];
126 if (!validate_operation(operation)) {
127 return ATAP_RESULT_ERROR_UNSUPPORTED_OPERATION;
128 }
129 if (!validate_curve(curve_type)) {
130 return ATAP_RESULT_ERROR_UNSUPPORTED_ALGORITHM;
131 }
132
133 atap_memcpy(ca_pubkey, &operation_start[10], ATAP_ECDH_KEY_LEN);
134
135 ret = ops->get_auth_key_type(ops, auth_key_type);
136 if (ret != ATAP_RESULT_OK) {
137 return ret;
138 }
139
140 ret = ops->ecdh_shared_secret_compute(ops,
141 curve_type,
142 ca_pubkey,
143 ca_request->device_pubkey,
144 session_shared_secret);
145 if (ret != ATAP_RESULT_OK) {
146 return ret;
147 }
148
149 return derive_session_key(ops,
150 ca_request->device_pubkey,
151 ca_pubkey,
152 session_shared_secret,
153 "KEY",
154 session_key,
155 ATAP_AES_128_KEY_LEN);
156 }
157
compute_auth_signature(AtapOps * ops,uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN],uint8_t device_pubkey[ATAP_ECDH_KEY_LEN],AtapInnerCaRequest * inner_ca_request)158 static AtapResult compute_auth_signature(
159 AtapOps* ops,
160 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN],
161 uint8_t device_pubkey[ATAP_ECDH_KEY_LEN],
162 AtapInnerCaRequest* inner_ca_request) {
163 AtapResult ret = 0;
164 /* read auth key cert chain */
165 ret = ops->read_auth_key_cert_chain(ops,
166 &inner_ca_request->auth_key_cert_chain);
167 if (ret != ATAP_RESULT_OK) {
168 return ret;
169 }
170 /* generate auth key signature */
171 return auth_key_signature_generate(ops,
172 device_pubkey,
173 ca_pubkey,
174 &inner_ca_request->signature.data,
175 &inner_ca_request->signature.data_length);
176 }
177
read_product_id_hash(AtapOps * ops,AtapInnerCaRequest * inner_ca_request)178 static AtapResult read_product_id_hash(AtapOps* ops,
179 AtapInnerCaRequest* inner_ca_request) {
180 AtapResult ret = 0;
181 uint8_t product_id[ATAP_PRODUCT_ID_LEN];
182
183 ret = ops->read_product_id(ops, product_id);
184 if (ret != ATAP_RESULT_OK) {
185 return ret;
186 }
187 return ops->sha256(
188 ops, product_id, ATAP_PRODUCT_ID_LEN, inner_ca_request->product_id_hash);
189 }
190
encrypt_inner_ca_request(AtapOps * ops,const AtapInnerCaRequest * inner_ca_request,AtapCaRequest * ca_request)191 static AtapResult encrypt_inner_ca_request(
192 AtapOps* ops,
193 const AtapInnerCaRequest* inner_ca_request,
194 AtapCaRequest* ca_request) {
195 AtapResult ret = 0;
196 uint32_t inner_ca_request_len = 0;
197 uint8_t* inner_ca_request_buf = NULL;
198
199 inner_ca_request_len = inner_ca_request_serialized_size(inner_ca_request);
200 inner_ca_request_buf = (uint8_t*)atap_malloc(inner_ca_request_len);
201 ca_request->encrypted_inner_ca_request.data =
202 (uint8_t*)atap_malloc(inner_ca_request_len);
203 ca_request->encrypted_inner_ca_request.data_length = inner_ca_request_len;
204 if (inner_ca_request_buf == NULL ||
205 ca_request->encrypted_inner_ca_request.data == NULL) {
206 return ATAP_RESULT_ERROR_OOM;
207 }
208 append_inner_ca_request_to_buf(inner_ca_request_buf, inner_ca_request);
209
210 /* generate IV */
211 ret = ops->get_random_bytes(ops, ca_request->iv, ATAP_GCM_IV_LEN);
212 if (ret != ATAP_RESULT_OK) {
213 goto out;
214 }
215
216 /* encrypt inner CA request with shared key */
217 ret = ops->aes_gcm_128_encrypt(ops,
218 inner_ca_request_buf,
219 inner_ca_request_len,
220 ca_request->iv,
221 session_key,
222 ca_request->encrypted_inner_ca_request.data,
223 ca_request->tag);
224 out:
225 atap_free(inner_ca_request_buf);
226 return ret;
227 }
228
decrypt_encrypted_message(AtapOps * ops,const uint8_t * buf,uint32_t buf_size,uint8_t * key,uint8_t ** plaintext,uint32_t * plaintext_len)229 static AtapResult decrypt_encrypted_message(AtapOps* ops,
230 const uint8_t* buf,
231 uint32_t buf_size,
232 uint8_t* key,
233 uint8_t** plaintext,
234 uint32_t* plaintext_len) {
235 const uint8_t *iv = NULL, *tag = NULL, *ciphertext = NULL;
236 uint32_t encrypted_len = 0;
237 uint8_t* buf_ptr = (uint8_t*)buf + ATAP_HEADER_LEN;
238
239 if (!validate_encrypted_message(buf, buf_size)) {
240 return ATAP_RESULT_ERROR_INVALID_INPUT;
241 }
242
243 iv = buf_ptr;
244 buf_ptr += ATAP_GCM_IV_LEN;
245 copy_uint32_from_buf(&buf_ptr, &encrypted_len);
246 ciphertext = buf_ptr;
247 buf_ptr += encrypted_len;
248 tag = buf_ptr;
249
250 *plaintext = (uint8_t*)atap_malloc(encrypted_len);
251 if (*plaintext == NULL) {
252 return ATAP_RESULT_ERROR_OOM;
253 }
254 *plaintext_len = encrypted_len;
255
256 return ops->aes_gcm_128_decrypt(
257 ops, ciphertext, *plaintext_len, iv, session_key, tag, *plaintext);
258 }
259
write_attestation_data(AtapOps * ops,uint8_t ** buf_ptr,AtapKeyType key_type)260 static AtapResult write_attestation_data(AtapOps* ops,
261 uint8_t** buf_ptr,
262 AtapKeyType key_type) {
263 AtapBlob key;
264 AtapCertChain cert_chain;
265 AtapResult ret = ATAP_RESULT_OK;
266
267 atap_memset(&key, 0, sizeof(key));
268 atap_memset(&cert_chain, 0, sizeof(cert_chain));
269
270 if (!copy_cert_chain_from_buf(buf_ptr, &cert_chain)) {
271 ret = ATAP_RESULT_ERROR_OOM;
272 goto out;
273 }
274 if (!copy_blob_from_buf(buf_ptr, &key)) {
275 ret = ATAP_RESULT_ERROR_OOM;
276 goto out;
277 }
278 if (key.data_length == 0 && cert_chain.entry_count) {
279 ret = ops->write_attestation_key(ops, key_type, NULL, &cert_chain);
280 } else if (key.data_length && cert_chain.entry_count) {
281 ret = ops->write_attestation_key(ops, key_type, &key, &cert_chain);
282 } else if (key.data_length && cert_chain.entry_count == 0) {
283 /* We never issue a key without a certificate chain */
284 ret = ATAP_RESULT_ERROR_INVALID_INPUT;
285 } else if (key_type != ATAP_KEY_TYPE_edDSA &&
286 key_type != ATAP_KEY_TYPE_SPECIAL &&
287 key_type != ATAP_KEY_TYPE_EPID) {
288 /* edDSA, EPID, and special purpose key are optional in version 1*/
289 ret = ATAP_RESULT_ERROR_INVALID_INPUT;
290 }
291
292 out:
293 free_blob(key);
294 free_cert_chain(cert_chain);
295 return ret;
296 }
297
write_inner_ca_response(AtapOps * ops,uint8_t * inner_ca_resp_ptr,uint32_t inner_ca_resp_len)298 static AtapResult write_inner_ca_response(AtapOps* ops,
299 uint8_t* inner_ca_resp_ptr,
300 uint32_t inner_ca_resp_len) {
301 AtapResult ret = 0;
302 uint8_t** buf_ptr = &inner_ca_resp_ptr;
303
304 if (!validate_inner_ca_response(
305 inner_ca_resp_ptr, inner_ca_resp_len, operation)) {
306 return ATAP_RESULT_ERROR_INVALID_INPUT;
307 }
308 ret = ops->write_hex_uuid(ops, &inner_ca_resp_ptr[ATAP_HEADER_LEN]);
309 if (ret != ATAP_RESULT_OK) {
310 return ret;
311 }
312 *buf_ptr += (ATAP_HEADER_LEN + ATAP_HEX_UUID_LEN);
313 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_RSA);
314 if (ret != ATAP_RESULT_OK) {
315 return ret;
316 }
317 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_ECDSA);
318 if (ret != ATAP_RESULT_OK) {
319 return ret;
320 }
321 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_edDSA);
322 /* Device may not support edDSA */
323 if (ret != ATAP_RESULT_OK && ret != ATAP_RESULT_ERROR_UNSUPPORTED_ALGORITHM) {
324 return ret;
325 }
326 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_EPID);
327 if (ret != ATAP_RESULT_OK) {
328 return ret;
329 }
330 /* Device may not support Special Cast key */
331 ret = write_attestation_data(ops, buf_ptr, ATAP_KEY_TYPE_SPECIAL);
332 if (ret != ATAP_RESULT_OK) {
333 return ret;
334 }
335 return ATAP_RESULT_OK;
336 }
337
atap_get_ca_request(AtapOps * ops,const uint8_t * operation_start,uint32_t operation_start_size,uint8_t ** ca_request_p,uint32_t * ca_request_size_p)338 AtapResult atap_get_ca_request(AtapOps* ops,
339 const uint8_t* operation_start,
340 uint32_t operation_start_size,
341 uint8_t** ca_request_p,
342 uint32_t* ca_request_size_p) {
343 AtapResult ret = 0;
344 AtapKeyType auth_key_type = 0;
345 AtapCaRequest ca_request;
346 AtapInnerCaRequest inner_ca_request;
347 uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN];
348
349 ret = initialize_session(ops,
350 operation_start,
351 operation_start_size,
352 &auth_key_type,
353 ca_pubkey,
354 &ca_request,
355 &inner_ca_request);
356 if (ret != ATAP_RESULT_OK) {
357 goto err;
358 }
359
360 if (auth_key_type != ATAP_KEY_TYPE_NONE) {
361 ret = compute_auth_signature(
362 ops, ca_pubkey, ca_request.device_pubkey, &inner_ca_request);
363 if (ret != ATAP_RESULT_OK) {
364 goto err;
365 }
366 }
367
368 if (operation == ATAP_OPERATION_CERTIFY) {
369 ret = read_available_public_keys(ops, &inner_ca_request);
370 if (ret != ATAP_RESULT_OK) {
371 goto err;
372 }
373 }
374
375 ret = read_product_id_hash(ops, &inner_ca_request);
376 if (ret != ATAP_RESULT_OK) {
377 goto err;
378 }
379
380 ret = encrypt_inner_ca_request(ops, &inner_ca_request, &ca_request);
381 if (ret != ATAP_RESULT_OK) {
382 goto err;
383 }
384
385 *ca_request_size_p = ca_request_serialized_size(&ca_request);
386 *ca_request_p = (uint8_t*)atap_malloc(*ca_request_size_p);
387 if (*ca_request_p == NULL) {
388 *ca_request_size_p = 0;
389 ret = ATAP_RESULT_ERROR_OOM;
390 goto err;
391 }
392 append_ca_request_to_buf(*ca_request_p, &ca_request);
393 goto out;
394
395 err:
396 /* clear global secrets */
397 atap_memset(session_shared_secret, 0, ATAP_ECDH_SHARED_SECRET_LEN);
398 atap_memset(session_key, 0, ATAP_AES_128_KEY_LEN);
399 *ca_request_p = NULL;
400 *ca_request_size_p = 0;
401 out:
402 free_inner_ca_request(inner_ca_request);
403 free_ca_request(ca_request);
404 return ret;
405 }
406
atap_set_ca_response(AtapOps * ops,const uint8_t * ca_response,uint32_t ca_response_size)407 AtapResult atap_set_ca_response(AtapOps* ops,
408 const uint8_t* ca_response,
409 uint32_t ca_response_size) {
410 AtapResult ret = 0;
411 uint8_t* inner_ca_resp = NULL;
412 uint8_t* inner_inner_ca_resp = NULL;
413 uint8_t* inner_ca_resp_ptr = NULL;
414 uint32_t inner_ca_resp_len = 0;
415 uint32_t inner_inner_ca_resp_len = 0;
416 uint8_t soc_global_key[ATAP_AES_128_KEY_LEN];
417
418 ret = decrypt_encrypted_message(ops,
419 ca_response,
420 ca_response_size,
421 session_key,
422 &inner_ca_resp,
423 &inner_ca_resp_len);
424 if (ret != ATAP_RESULT_OK) {
425 goto out;
426 }
427 inner_ca_resp_ptr = inner_ca_resp;
428 if (operation == ATAP_OPERATION_ISSUE_ENCRYPTED) {
429 /* Decrypt Encrypted Inner CA Response (encrypted) with SoC global key */
430 ret = ops->read_soc_global_key(ops, soc_global_key);
431 if (ret != ATAP_RESULT_OK) {
432 goto out;
433 }
434 ret = decrypt_encrypted_message(ops,
435 inner_ca_resp,
436 inner_ca_resp_len,
437 soc_global_key,
438 &inner_inner_ca_resp,
439 &inner_inner_ca_resp_len);
440 if (ret != ATAP_RESULT_OK) {
441 goto out;
442 }
443 inner_ca_resp_ptr = inner_inner_ca_resp;
444 inner_ca_resp_len = inner_inner_ca_resp_len;
445 }
446 ret = write_inner_ca_response(ops, inner_ca_resp_ptr, inner_ca_resp_len);
447
448 out:
449 if (inner_ca_resp) {
450 atap_free(inner_ca_resp);
451 }
452 if (inner_inner_ca_resp) {
453 atap_free(inner_inner_ca_resp);
454 }
455 return ret;
456 }
457