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_util.h" 18 19 #include "atap_ops.h" 20 21 const char* atap_basename(const char* str) { 22 int64_t n = 0; 23 size_t len = atap_strlen(str); 24 25 if (len >= 2) { 26 for (n = len - 2; n >= 0; n--) { 27 if (str[n] == '/') { 28 return str + n + 1; 29 } 30 } 31 } 32 return str; 33 } 34 35 uint8_t* append_to_buf(uint8_t* buf, const void* data, uint32_t data_size) { 36 atap_memcpy(buf, data, data_size); 37 return buf + data_size; 38 } 39 40 uint8_t* append_uint32_to_buf(uint8_t* buf, uint32_t x) { 41 return append_to_buf(buf, &x, sizeof(uint32_t)); 42 } 43 44 uint8_t* append_header_to_buf(uint8_t* buf, uint32_t message_length) { 45 buf[0] = ATAP_PROTOCOL_VERSION; 46 atap_memset(&buf[1], 0, 3); // reserved 47 buf += 4; 48 return append_uint32_to_buf(buf, message_length); 49 } 50 51 uint8_t* append_blob_to_buf(uint8_t* buf, const AtapBlob* blob) { 52 atap_assert(blob->data_length == 0 || blob->data); 53 buf = append_uint32_to_buf(buf, blob->data_length); 54 if (blob->data_length > 0) { 55 buf = append_to_buf(buf, blob->data, blob->data_length); 56 } 57 return buf; 58 } 59 60 uint8_t* append_cert_chain_to_buf(uint8_t* buf, 61 const AtapCertChain* cert_chain) { 62 uint32_t cert_chain_size = 63 cert_chain_serialized_size(cert_chain) - sizeof(uint32_t); 64 uint32_t i = 0; 65 uint8_t* local_buf = buf; 66 67 /* Append size of cert chain, as it is a Variable field. */ 68 local_buf = append_uint32_to_buf(local_buf, cert_chain_size); 69 70 for (i = 0; i < cert_chain->entry_count; ++i) { 71 local_buf = append_blob_to_buf(local_buf, &cert_chain->entries[i]); 72 } 73 atap_assert(local_buf == (buf + cert_chain_size + sizeof(uint32_t))); 74 return local_buf; 75 } 76 77 uint8_t* append_ca_request_to_buf(uint8_t* buf, 78 const AtapCaRequest* ca_request) { 79 uint32_t ca_request_len = ca_request_serialized_size(ca_request); 80 81 buf = append_header_to_buf(buf, ca_request_len - ATAP_HEADER_LEN); 82 buf = append_to_buf(buf, ca_request->device_pubkey, ATAP_ECDH_KEY_LEN); 83 buf = append_to_buf(buf, ca_request->iv, ATAP_GCM_IV_LEN); 84 buf = append_blob_to_buf(buf, &ca_request->encrypted_inner_ca_request); 85 return append_to_buf(buf, ca_request->tag, ATAP_GCM_TAG_LEN); 86 } 87 88 uint8_t* append_inner_ca_request_to_buf( 89 uint8_t* buf, const AtapInnerCaRequest* inner_ca_request) { 90 uint32_t inner_ca_request_len = 91 inner_ca_request_serialized_size(inner_ca_request); 92 93 buf = append_header_to_buf(buf, inner_ca_request_len - ATAP_HEADER_LEN); 94 buf = append_cert_chain_to_buf(buf, &inner_ca_request->auth_key_cert_chain); 95 buf = append_blob_to_buf(buf, &inner_ca_request->signature); 96 buf = append_to_buf( 97 buf, inner_ca_request->product_id_hash, ATAP_SHA256_DIGEST_LEN); 98 buf = append_blob_to_buf(buf, &inner_ca_request->RSA_pubkey); 99 buf = append_blob_to_buf(buf, &inner_ca_request->ECDSA_pubkey); 100 return append_blob_to_buf(buf, &inner_ca_request->edDSA_pubkey); 101 } 102 103 void copy_from_buf(uint8_t** buf_ptr, void* data, uint32_t data_size) { 104 atap_memcpy(data, *buf_ptr, data_size); 105 *buf_ptr += data_size; 106 } 107 108 void copy_uint32_from_buf(uint8_t** buf_ptr, uint32_t* x) { 109 copy_from_buf(buf_ptr, x, sizeof(uint32_t)); 110 } 111 112 bool copy_blob_from_buf(uint8_t** buf_ptr, AtapBlob* blob) { 113 atap_memset(blob, 0, sizeof(AtapBlob)); 114 copy_uint32_from_buf(buf_ptr, &blob->data_length); 115 if (blob->data_length > ATAP_BLOB_LEN_MAX) { 116 return false; 117 } 118 if (blob->data_length) { 119 blob->data = (uint8_t*)atap_malloc(blob->data_length); 120 if (blob->data == NULL) { 121 return false; 122 } 123 copy_from_buf(buf_ptr, blob->data, blob->data_length); 124 } 125 return true; 126 } 127 128 bool copy_cert_chain_from_buf(uint8_t** buf_ptr, AtapCertChain* cert_chain) { 129 uint32_t cert_chain_size = 0; 130 int32_t bytes_remaining = 0; 131 size_t i = 0; 132 bool retval = true; 133 134 atap_memset(cert_chain, 0, sizeof(AtapCertChain)); 135 136 /* Copy size of cert chain, as it is a Variable field. */ 137 copy_from_buf(buf_ptr, &cert_chain_size, sizeof(cert_chain_size)); 138 139 if (cert_chain_size > ATAP_CERT_CHAIN_LEN_MAX) { 140 return false; 141 } 142 if (cert_chain_size == 0) { 143 return true; 144 } 145 bytes_remaining = cert_chain_size; 146 for (i = 0; i < ATAP_CERT_CHAIN_ENTRIES_MAX; ++i) { 147 if (!copy_blob_from_buf(buf_ptr, &cert_chain->entries[i])) { 148 retval = false; 149 break; 150 } 151 ++cert_chain->entry_count; 152 bytes_remaining -= (sizeof(uint32_t) + cert_chain->entries[i].data_length); 153 if (bytes_remaining <= 0) { 154 retval = (bytes_remaining == 0); 155 break; 156 } 157 } 158 if (retval == false) { 159 free_cert_chain(*cert_chain); 160 } 161 return retval; 162 } 163 164 uint32_t blob_serialized_size(const AtapBlob* blob) { 165 return sizeof(uint32_t) + blob->data_length; 166 } 167 168 uint32_t cert_chain_serialized_size(const AtapCertChain* cert_chain) { 169 uint32_t size = sizeof(uint32_t); 170 uint32_t i = 0; 171 172 for (i = 0; i < cert_chain->entry_count; ++i) { 173 size += sizeof(uint32_t) + cert_chain->entries[i].data_length; 174 } 175 return size; 176 } 177 178 uint32_t ca_request_serialized_size(const AtapCaRequest* ca_request) { 179 uint32_t size = 180 ATAP_HEADER_LEN + ATAP_ECDH_KEY_LEN + ATAP_GCM_IV_LEN + ATAP_GCM_TAG_LEN; 181 182 size += blob_serialized_size(&ca_request->encrypted_inner_ca_request); 183 return size; 184 } 185 186 uint32_t inner_ca_request_serialized_size( 187 const AtapInnerCaRequest* inner_ca_request) { 188 uint32_t size = ATAP_HEADER_LEN + ATAP_SHA256_DIGEST_LEN; 189 190 size += cert_chain_serialized_size(&inner_ca_request->auth_key_cert_chain); 191 size += blob_serialized_size(&inner_ca_request->signature); 192 size += blob_serialized_size(&inner_ca_request->RSA_pubkey); 193 size += blob_serialized_size(&inner_ca_request->ECDSA_pubkey); 194 size += blob_serialized_size(&inner_ca_request->edDSA_pubkey); 195 return size; 196 } 197 198 void free_blob(AtapBlob blob) { 199 if (blob.data) { 200 atap_free(blob.data); 201 } 202 blob.data_length = 0; 203 } 204 205 void free_cert_chain(AtapCertChain cert_chain) { 206 unsigned int i = 0; 207 208 for (i = 0; i < cert_chain.entry_count; ++i) { 209 if (cert_chain.entries[i].data) { 210 atap_free(cert_chain.entries[i].data); 211 } 212 cert_chain.entries[i].data_length = 0; 213 } 214 atap_memset(&cert_chain, 0, sizeof(AtapCertChain)); 215 } 216 217 void free_ca_request(AtapCaRequest ca_request) { 218 free_blob(ca_request.encrypted_inner_ca_request); 219 } 220 221 void free_inner_ca_request(AtapInnerCaRequest inner_ca_request) { 222 free_cert_chain(inner_ca_request.auth_key_cert_chain); 223 free_blob(inner_ca_request.signature); 224 free_blob(inner_ca_request.RSA_pubkey); 225 free_blob(inner_ca_request.ECDSA_pubkey); 226 free_blob(inner_ca_request.edDSA_pubkey); 227 } 228 229 bool validate_operation(AtapOperation operation) { 230 if (operation != ATAP_OPERATION_CERTIFY && 231 operation != ATAP_OPERATION_ISSUE && 232 operation != ATAP_OPERATION_ISSUE_ENCRYPTED) { 233 return false; 234 } 235 return true; 236 } 237 238 bool validate_curve(AtapCurveType curve) { 239 if (curve != ATAP_CURVE_TYPE_P256 && curve != ATAP_CURVE_TYPE_X25519) { 240 return false; 241 } 242 return true; 243 } 244 245 bool validate_encrypted_message(const uint8_t* buf, uint32_t buf_size) { 246 uint32_t encrypted_len, message_len; 247 uint8_t* buf_ptr = (uint8_t*)buf; 248 249 if (buf_size < 250 ATAP_HEADER_LEN + ATAP_GCM_IV_LEN + sizeof(uint32_t) + ATAP_GCM_TAG_LEN) { 251 return false; 252 } 253 if (buf[0] != ATAP_PROTOCOL_VERSION) { 254 return false; 255 } 256 buf_ptr += 4; 257 copy_uint32_from_buf(&buf_ptr, &message_len); 258 if (message_len != buf_size - ATAP_HEADER_LEN) { 259 return false; 260 } 261 buf_ptr += ATAP_GCM_IV_LEN; 262 copy_uint32_from_buf(&buf_ptr, &encrypted_len); 263 if (encrypted_len != 264 message_len - ATAP_GCM_IV_LEN - sizeof(uint32_t) - ATAP_GCM_TAG_LEN) { 265 return false; 266 } 267 return true; 268 } 269 270 bool validate_inner_ca_response(const uint8_t* buf, 271 uint32_t buf_size, 272 AtapOperation operation) { 273 uint32_t cert_chain_len = 0, len = 0; 274 size_t i = 0; 275 int tmp = 0; 276 uint8_t* buf_ptr = (uint8_t*)buf; 277 278 if (buf_size < ATAP_HEADER_LEN + ATAP_HEX_UUID_LEN + 279 ATAP_INNER_CA_RESPONSE_FIELDS * sizeof(uint32_t)) { 280 return false; 281 } 282 if (buf[0] != ATAP_PROTOCOL_VERSION) { 283 return false; 284 } 285 buf_ptr += 4; 286 copy_uint32_from_buf(&buf_ptr, &len); 287 if (len != buf_size - ATAP_HEADER_LEN) { 288 return false; 289 } 290 buf_ptr += ATAP_HEX_UUID_LEN; 291 for (i = 0; i < ATAP_INNER_CA_RESPONSE_FIELDS; ++i) { 292 /* Odd indices are private keys */ 293 if (i % 2) { 294 copy_uint32_from_buf(&buf_ptr, &len); 295 /* Product keys (non special purpose) are omitted on certify operation. */ 296 if (operation == ATAP_OPERATION_CERTIFY && 297 i != ATAP_INNER_CA_RESPONSE_FIELDS - 1 && len != 0) { 298 return false; 299 } 300 if (len > ATAP_KEY_LEN_MAX) { 301 return false; 302 } 303 buf_ptr += len; 304 } else { 305 copy_uint32_from_buf(&buf_ptr, &cert_chain_len); 306 if (cert_chain_len > ATAP_CERT_CHAIN_LEN_MAX) { 307 return false; 308 } 309 tmp = cert_chain_len; 310 while (tmp) { 311 copy_uint32_from_buf(&buf_ptr, &len); 312 if (len > ATAP_CERT_LEN_MAX) { 313 return false; 314 } 315 buf_ptr += len; 316 tmp -= (sizeof(uint32_t) + len); 317 /* Length value list was not constructed correctly. */ 318 if (tmp < 0) { 319 return false; 320 } 321 } 322 } 323 } 324 if (buf_ptr != buf + buf_size) { 325 return false; 326 } 327 return true; 328 } 329 330 AtapResult derive_session_key( 331 AtapOps* ops, 332 const uint8_t device_pubkey[ATAP_ECDH_KEY_LEN], 333 const uint8_t ca_pubkey[ATAP_ECDH_KEY_LEN], 334 const uint8_t shared_secret[ATAP_ECDH_SHARED_SECRET_LEN], 335 const char* info, 336 uint8_t* okm, 337 uint32_t okm_len) { 338 uint8_t salt[2 * ATAP_ECDH_KEY_LEN]; 339 340 atap_memcpy(salt, ca_pubkey, ATAP_ECDH_KEY_LEN); 341 atap_memcpy(salt + ATAP_ECDH_KEY_LEN, device_pubkey, ATAP_ECDH_KEY_LEN); 342 343 return ops->hkdf_sha256(ops, 344 salt, 345 sizeof(salt), 346 shared_secret, 347 ATAP_ECDH_SHARED_SECRET_LEN, 348 (const uint8_t*)info, 349 atap_strlen(info), 350 okm, 351 okm_len); 352 } 353