1f540a430SEd Maste /* 2f540a430SEd Maste * Copyright (c) 2021 Yubico AB. All rights reserved. 3f540a430SEd Maste * Use of this source code is governed by a BSD-style 4f540a430SEd Maste * license that can be found in the LICENSE file. 5f540a430SEd Maste */ 6f540a430SEd Maste 7f540a430SEd Maste /* 8f540a430SEd Maste * Trusted Platform Module (TPM) 2.0 attestation support. Documentation 9f540a430SEd Maste * references are relative to revision 01.38 of the TPM 2.0 specification. 10f540a430SEd Maste */ 11f540a430SEd Maste 12f540a430SEd Maste #include <openssl/sha.h> 13f540a430SEd Maste 14f540a430SEd Maste #include "packed.h" 15f540a430SEd Maste #include "fido.h" 16f540a430SEd Maste 17f540a430SEd Maste /* Part 1, 4.89: TPM_GENERATED_VALUE */ 18f540a430SEd Maste #define TPM_MAGIC 0xff544347 19f540a430SEd Maste 20f540a430SEd Maste /* Part 2, 6.3: TPM_ALG_ID */ 21f540a430SEd Maste #define TPM_ALG_RSA 0x0001 22f540a430SEd Maste #define TPM_ALG_SHA256 0x000b 23f540a430SEd Maste #define TPM_ALG_NULL 0x0010 24*3e696dfbSEd Maste #define TPM_ALG_ECC 0x0023 25*3e696dfbSEd Maste 26*3e696dfbSEd Maste /* Part 2, 6.4: TPM_ECC_CURVE */ 27*3e696dfbSEd Maste #define TPM_ECC_P256 0x0003 28f540a430SEd Maste 29f540a430SEd Maste /* Part 2, 6.9: TPM_ST_ATTEST_CERTIFY */ 30f540a430SEd Maste #define TPM_ST_CERTIFY 0x8017 31f540a430SEd Maste 32f540a430SEd Maste /* Part 2, 8.3: TPMA_OBJECT */ 33f540a430SEd Maste #define TPMA_RESERVED 0xfff8f309 /* reserved bits; must be zero */ 34f540a430SEd Maste #define TPMA_FIXED 0x00000002 /* object has fixed hierarchy */ 35f540a430SEd Maste #define TPMA_CLEAR 0x00000004 /* object persists */ 36f540a430SEd Maste #define TPMA_FIXED_P 0x00000010 /* object has fixed parent */ 37f540a430SEd Maste #define TPMA_SENSITIVE 0x00000020 /* data originates within tpm */ 38*3e696dfbSEd Maste #define TPMA_SIGN 0x00040000 /* object may sign */ 39f540a430SEd Maste 40f540a430SEd Maste /* Part 2, 10.4.2: TPM2B_DIGEST */ 41f540a430SEd Maste PACKED_TYPE(tpm_sha256_digest_t, 42f540a430SEd Maste struct tpm_sha256_digest { 43f540a430SEd Maste uint16_t size; /* sizeof(body) */ 44f540a430SEd Maste uint8_t body[32]; 45f540a430SEd Maste }) 46f540a430SEd Maste 47f540a430SEd Maste /* Part 2, 10.4.3: TPM2B_DATA */ 48f540a430SEd Maste PACKED_TYPE(tpm_sha1_data_t, 49f540a430SEd Maste struct tpm_sha1_data { 50f540a430SEd Maste uint16_t size; /* sizeof(body */ 51f540a430SEd Maste uint8_t body[20]; 52f540a430SEd Maste }) 53f540a430SEd Maste 54f540a430SEd Maste /* Part 2, 10.5.3: TPM2B_NAME */ 55f540a430SEd Maste PACKED_TYPE(tpm_sha256_name_t, 56f540a430SEd Maste struct tpm_sha256_name { 57f540a430SEd Maste uint16_t size; /* sizeof(alg) + sizeof(body) */ 58f540a430SEd Maste uint16_t alg; /* TPM_ALG_SHA256 */ 59f540a430SEd Maste uint8_t body[32]; 60f540a430SEd Maste }) 61f540a430SEd Maste 62f540a430SEd Maste /* Part 2, 10.11.1: TPMS_CLOCK_INFO */ 63f540a430SEd Maste PACKED_TYPE(tpm_clock_info_t, 64f540a430SEd Maste struct tpm_clock_info { 65f540a430SEd Maste uint64_t timestamp_ms; 66f540a430SEd Maste uint32_t reset_count; /* obfuscated by tpm */ 67f540a430SEd Maste uint32_t restart_count; /* obfuscated by tpm */ 68f540a430SEd Maste uint8_t safe; /* 1 if timestamp_ms is current */ 69f540a430SEd Maste }) 70f540a430SEd Maste 71f540a430SEd Maste /* Part 2, 10.12.8 TPMS_ATTEST */ 72f540a430SEd Maste PACKED_TYPE(tpm_sha1_attest_t, 73f540a430SEd Maste struct tpm_sha1_attest { 74f540a430SEd Maste uint32_t magic; /* TPM_MAGIC */ 75f540a430SEd Maste uint16_t type; /* TPM_ST_ATTEST_CERTIFY */ 76f540a430SEd Maste tpm_sha256_name_t signer; /* full tpm path of signing key */ 77f540a430SEd Maste tpm_sha1_data_t data; /* signed sha1 */ 78f540a430SEd Maste tpm_clock_info_t clock; 79f540a430SEd Maste uint64_t fwversion; /* obfuscated by tpm */ 80*3e696dfbSEd Maste tpm_sha256_name_t name; /* sha256 of tpm_rs256_pubarea_t */ 81f540a430SEd Maste tpm_sha256_name_t qual_name; /* full tpm path of attested key */ 82f540a430SEd Maste }) 83f540a430SEd Maste 84f540a430SEd Maste /* Part 2, 11.2.4.5: TPM2B_PUBLIC_KEY_RSA */ 85*3e696dfbSEd Maste PACKED_TYPE(tpm_rs256_key_t, 86*3e696dfbSEd Maste struct tpm_rs256_key { 87f540a430SEd Maste uint16_t size; /* sizeof(body) */ 88f540a430SEd Maste uint8_t body[256]; 89f540a430SEd Maste }) 90f540a430SEd Maste 91*3e696dfbSEd Maste /* Part 2, 11.2.5.1: TPM2B_ECC_PARAMETER */ 92*3e696dfbSEd Maste PACKED_TYPE(tpm_es256_coord_t, 93*3e696dfbSEd Maste struct tpm_es256_coord { 94*3e696dfbSEd Maste uint16_t size; /* sizeof(body) */ 95*3e696dfbSEd Maste uint8_t body[32]; 96*3e696dfbSEd Maste }) 97*3e696dfbSEd Maste 98*3e696dfbSEd Maste /* Part 2, 11.2.5.2: TPMS_ECC_POINT */ 99*3e696dfbSEd Maste PACKED_TYPE(tpm_es256_point_t, 100*3e696dfbSEd Maste struct tpm_es256_point { 101*3e696dfbSEd Maste tpm_es256_coord_t x; 102*3e696dfbSEd Maste tpm_es256_coord_t y; 103*3e696dfbSEd Maste }) 104*3e696dfbSEd Maste 105f540a430SEd Maste /* Part 2, 12.2.3.5: TPMS_RSA_PARMS */ 106*3e696dfbSEd Maste PACKED_TYPE(tpm_rs256_param_t, 107*3e696dfbSEd Maste struct tpm_rs256_param { 108f540a430SEd Maste uint16_t symmetric; /* TPM_ALG_NULL */ 109f540a430SEd Maste uint16_t scheme; /* TPM_ALG_NULL */ 110f540a430SEd Maste uint16_t keybits; /* 2048 */ 111f540a430SEd Maste uint32_t exponent; /* zero (meaning 2^16 + 1) */ 112f540a430SEd Maste }) 113f540a430SEd Maste 114*3e696dfbSEd Maste /* Part 2, 12.2.3.6: TPMS_ECC_PARMS */ 115*3e696dfbSEd Maste PACKED_TYPE(tpm_es256_param_t, 116*3e696dfbSEd Maste struct tpm_es256_param { 117*3e696dfbSEd Maste uint16_t symmetric; /* TPM_ALG_NULL */ 118*3e696dfbSEd Maste uint16_t scheme; /* TPM_ALG_NULL */ 119*3e696dfbSEd Maste uint16_t curve_id; /* TPM_ECC_P256 */ 120*3e696dfbSEd Maste uint16_t kdf; /* TPM_ALG_NULL */ 121*3e696dfbSEd Maste }) 122*3e696dfbSEd Maste 123f540a430SEd Maste /* Part 2, 12.2.4: TPMT_PUBLIC */ 124*3e696dfbSEd Maste PACKED_TYPE(tpm_rs256_pubarea_t, 125*3e696dfbSEd Maste struct tpm_rs256_pubarea { 126f540a430SEd Maste uint16_t alg; /* TPM_ALG_RSA */ 127f540a430SEd Maste uint16_t hash; /* TPM_ALG_SHA256 */ 128f540a430SEd Maste uint32_t attr; 129f540a430SEd Maste tpm_sha256_digest_t policy; /* must be present? */ 130*3e696dfbSEd Maste tpm_rs256_param_t param; 131*3e696dfbSEd Maste tpm_rs256_key_t key; 132*3e696dfbSEd Maste }) 133*3e696dfbSEd Maste 134*3e696dfbSEd Maste /* Part 2, 12.2.4: TPMT_PUBLIC */ 135*3e696dfbSEd Maste PACKED_TYPE(tpm_es256_pubarea_t, 136*3e696dfbSEd Maste struct tpm_es256_pubarea { 137*3e696dfbSEd Maste uint16_t alg; /* TPM_ALG_ECC */ 138*3e696dfbSEd Maste uint16_t hash; /* TPM_ALG_SHA256 */ 139*3e696dfbSEd Maste uint32_t attr; 140*3e696dfbSEd Maste tpm_sha256_digest_t policy; /* must be present? */ 141*3e696dfbSEd Maste tpm_es256_param_t param; 142*3e696dfbSEd Maste tpm_es256_point_t point; 143f540a430SEd Maste }) 144f540a430SEd Maste 145f540a430SEd Maste static int 146f540a430SEd Maste get_signed_sha1(tpm_sha1_data_t *dgst, const fido_blob_t *authdata, 147f540a430SEd Maste const fido_blob_t *clientdata) 148f540a430SEd Maste { 149f540a430SEd Maste const EVP_MD *md = NULL; 150f540a430SEd Maste EVP_MD_CTX *ctx = NULL; 151f540a430SEd Maste int ok = -1; 152f540a430SEd Maste 153f540a430SEd Maste if ((dgst->size = sizeof(dgst->body)) != SHA_DIGEST_LENGTH || 154f540a430SEd Maste (md = EVP_sha1()) == NULL || 155f540a430SEd Maste (ctx = EVP_MD_CTX_new()) == NULL || 156f540a430SEd Maste EVP_DigestInit_ex(ctx, md, NULL) != 1 || 157f540a430SEd Maste EVP_DigestUpdate(ctx, authdata->ptr, authdata->len) != 1 || 158f540a430SEd Maste EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 || 159f540a430SEd Maste EVP_DigestFinal_ex(ctx, dgst->body, NULL) != 1) { 160f540a430SEd Maste fido_log_debug("%s: sha1", __func__); 161f540a430SEd Maste goto fail; 162f540a430SEd Maste } 163f540a430SEd Maste 164f540a430SEd Maste ok = 0; 165f540a430SEd Maste fail: 166f540a430SEd Maste EVP_MD_CTX_free(ctx); 167f540a430SEd Maste 168f540a430SEd Maste return (ok); 169f540a430SEd Maste } 170f540a430SEd Maste 171f540a430SEd Maste static int 172f540a430SEd Maste get_signed_name(tpm_sha256_name_t *name, const fido_blob_t *pubarea) 173f540a430SEd Maste { 174f540a430SEd Maste name->alg = TPM_ALG_SHA256; 175f540a430SEd Maste name->size = sizeof(name->alg) + sizeof(name->body); 176f540a430SEd Maste if (sizeof(name->body) != SHA256_DIGEST_LENGTH || 177f540a430SEd Maste SHA256(pubarea->ptr, pubarea->len, name->body) != name->body) { 178f540a430SEd Maste fido_log_debug("%s: sha256", __func__); 179f540a430SEd Maste return -1; 180f540a430SEd Maste } 181f540a430SEd Maste 182f540a430SEd Maste return 0; 183f540a430SEd Maste } 184f540a430SEd Maste 185f540a430SEd Maste static void 186*3e696dfbSEd Maste bswap_rs256_pubarea(tpm_rs256_pubarea_t *x) 187f540a430SEd Maste { 188f540a430SEd Maste x->alg = htobe16(x->alg); 189f540a430SEd Maste x->hash = htobe16(x->hash); 190f540a430SEd Maste x->attr = htobe32(x->attr); 191f540a430SEd Maste x->policy.size = htobe16(x->policy.size); 192f540a430SEd Maste x->param.symmetric = htobe16(x->param.symmetric); 193f540a430SEd Maste x->param.scheme = htobe16(x->param.scheme); 194f540a430SEd Maste x->param.keybits = htobe16(x->param.keybits); 195f540a430SEd Maste x->key.size = htobe16(x->key.size); 196f540a430SEd Maste } 197f540a430SEd Maste 198f540a430SEd Maste static void 199*3e696dfbSEd Maste bswap_es256_pubarea(tpm_es256_pubarea_t *x) 200*3e696dfbSEd Maste { 201*3e696dfbSEd Maste x->alg = htobe16(x->alg); 202*3e696dfbSEd Maste x->hash = htobe16(x->hash); 203*3e696dfbSEd Maste x->attr = htobe32(x->attr); 204*3e696dfbSEd Maste x->policy.size = htobe16(x->policy.size); 205*3e696dfbSEd Maste x->param.symmetric = htobe16(x->param.symmetric); 206*3e696dfbSEd Maste x->param.scheme = htobe16(x->param.scheme); 207*3e696dfbSEd Maste x->param.curve_id = htobe16(x->param.curve_id); 208*3e696dfbSEd Maste x->param.kdf = htobe16(x->param.kdf); 209*3e696dfbSEd Maste x->point.x.size = htobe16(x->point.x.size); 210*3e696dfbSEd Maste x->point.y.size = htobe16(x->point.y.size); 211*3e696dfbSEd Maste } 212*3e696dfbSEd Maste 213*3e696dfbSEd Maste static void 214f540a430SEd Maste bswap_sha1_certinfo(tpm_sha1_attest_t *x) 215f540a430SEd Maste { 216f540a430SEd Maste x->magic = htobe32(x->magic); 217f540a430SEd Maste x->type = htobe16(x->type); 218f540a430SEd Maste x->signer.size = htobe16(x->signer.size); 219f540a430SEd Maste x->data.size = htobe16(x->data.size); 220f540a430SEd Maste x->name.alg = htobe16(x->name.alg); 221f540a430SEd Maste x->name.size = htobe16(x->name.size); 222f540a430SEd Maste } 223f540a430SEd Maste 224f540a430SEd Maste static int 225*3e696dfbSEd Maste check_rs256_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk) 226f540a430SEd Maste { 227*3e696dfbSEd Maste const tpm_rs256_pubarea_t *actual; 228*3e696dfbSEd Maste tpm_rs256_pubarea_t expected; 229f540a430SEd Maste int ok; 230f540a430SEd Maste 231f540a430SEd Maste if (buf->len != sizeof(*actual)) { 232f540a430SEd Maste fido_log_debug("%s: buf->len=%zu", __func__, buf->len); 233f540a430SEd Maste return -1; 234f540a430SEd Maste } 235f540a430SEd Maste actual = (const void *)buf->ptr; 236f540a430SEd Maste 237f540a430SEd Maste memset(&expected, 0, sizeof(expected)); 238f540a430SEd Maste expected.alg = TPM_ALG_RSA; 239f540a430SEd Maste expected.hash = TPM_ALG_SHA256; 240f540a430SEd Maste expected.attr = be32toh(actual->attr); 241f540a430SEd Maste expected.attr &= ~(TPMA_RESERVED|TPMA_CLEAR); 242f540a430SEd Maste expected.attr |= (TPMA_FIXED|TPMA_FIXED_P|TPMA_SENSITIVE|TPMA_SIGN); 243f540a430SEd Maste expected.policy = actual->policy; 244f540a430SEd Maste expected.policy.size = sizeof(expected.policy.body); 245f540a430SEd Maste expected.param.symmetric = TPM_ALG_NULL; 246f540a430SEd Maste expected.param.scheme = TPM_ALG_NULL; 247f540a430SEd Maste expected.param.keybits = 2048; 248f540a430SEd Maste expected.param.exponent = 0; /* meaning 2^16+1 */ 249f540a430SEd Maste expected.key.size = sizeof(expected.key.body); 250f540a430SEd Maste memcpy(&expected.key.body, &pk->n, sizeof(expected.key.body)); 251*3e696dfbSEd Maste bswap_rs256_pubarea(&expected); 252*3e696dfbSEd Maste 253*3e696dfbSEd Maste ok = timingsafe_bcmp(&expected, actual, sizeof(expected)); 254*3e696dfbSEd Maste explicit_bzero(&expected, sizeof(expected)); 255*3e696dfbSEd Maste 256*3e696dfbSEd Maste return ok != 0 ? -1 : 0; 257*3e696dfbSEd Maste } 258*3e696dfbSEd Maste 259*3e696dfbSEd Maste static int 260*3e696dfbSEd Maste check_es256_pubarea(const fido_blob_t *buf, const es256_pk_t *pk) 261*3e696dfbSEd Maste { 262*3e696dfbSEd Maste const tpm_es256_pubarea_t *actual; 263*3e696dfbSEd Maste tpm_es256_pubarea_t expected; 264*3e696dfbSEd Maste int ok; 265*3e696dfbSEd Maste 266*3e696dfbSEd Maste if (buf->len != sizeof(*actual)) { 267*3e696dfbSEd Maste fido_log_debug("%s: buf->len=%zu", __func__, buf->len); 268*3e696dfbSEd Maste return -1; 269*3e696dfbSEd Maste } 270*3e696dfbSEd Maste actual = (const void *)buf->ptr; 271*3e696dfbSEd Maste 272*3e696dfbSEd Maste memset(&expected, 0, sizeof(expected)); 273*3e696dfbSEd Maste expected.alg = TPM_ALG_ECC; 274*3e696dfbSEd Maste expected.hash = TPM_ALG_SHA256; 275*3e696dfbSEd Maste expected.attr = be32toh(actual->attr); 276*3e696dfbSEd Maste expected.attr &= ~(TPMA_RESERVED|TPMA_CLEAR); 277*3e696dfbSEd Maste expected.attr |= (TPMA_FIXED|TPMA_FIXED_P|TPMA_SENSITIVE|TPMA_SIGN); 278*3e696dfbSEd Maste expected.policy = actual->policy; 279*3e696dfbSEd Maste expected.policy.size = sizeof(expected.policy.body); 280*3e696dfbSEd Maste expected.param.symmetric = TPM_ALG_NULL; 281*3e696dfbSEd Maste expected.param.scheme = TPM_ALG_NULL; /* TCG Alg. Registry, 5.2.4 */ 282*3e696dfbSEd Maste expected.param.curve_id = TPM_ECC_P256; 283*3e696dfbSEd Maste expected.param.kdf = TPM_ALG_NULL; 284*3e696dfbSEd Maste expected.point.x.size = sizeof(expected.point.x.body); 285*3e696dfbSEd Maste expected.point.y.size = sizeof(expected.point.y.body); 286*3e696dfbSEd Maste memcpy(&expected.point.x.body, &pk->x, sizeof(expected.point.x.body)); 287*3e696dfbSEd Maste memcpy(&expected.point.y.body, &pk->y, sizeof(expected.point.y.body)); 288*3e696dfbSEd Maste bswap_es256_pubarea(&expected); 289f540a430SEd Maste 290f540a430SEd Maste ok = timingsafe_bcmp(&expected, actual, sizeof(expected)); 291f540a430SEd Maste explicit_bzero(&expected, sizeof(expected)); 292f540a430SEd Maste 293f540a430SEd Maste return ok != 0 ? -1 : 0; 294f540a430SEd Maste } 295f540a430SEd Maste 296f540a430SEd Maste static int 297f540a430SEd Maste check_sha1_certinfo(const fido_blob_t *buf, const fido_blob_t *clientdata_hash, 298f540a430SEd Maste const fido_blob_t *authdata_raw, const fido_blob_t *pubarea) 299f540a430SEd Maste { 300f540a430SEd Maste const tpm_sha1_attest_t *actual; 301f540a430SEd Maste tpm_sha1_attest_t expected; 302f540a430SEd Maste tpm_sha1_data_t signed_data; 303f540a430SEd Maste tpm_sha256_name_t signed_name; 304f540a430SEd Maste int ok = -1; 305f540a430SEd Maste 306f540a430SEd Maste memset(&signed_data, 0, sizeof(signed_data)); 307f540a430SEd Maste memset(&signed_name, 0, sizeof(signed_name)); 308f540a430SEd Maste 309f540a430SEd Maste if (get_signed_sha1(&signed_data, authdata_raw, clientdata_hash) < 0 || 310f540a430SEd Maste get_signed_name(&signed_name, pubarea) < 0) { 311f540a430SEd Maste fido_log_debug("%s: get_signed_sha1/name", __func__); 312f540a430SEd Maste goto fail; 313f540a430SEd Maste } 314f540a430SEd Maste if (buf->len != sizeof(*actual)) { 315f540a430SEd Maste fido_log_debug("%s: buf->len=%zu", __func__, buf->len); 316f540a430SEd Maste goto fail; 317f540a430SEd Maste } 318f540a430SEd Maste actual = (const void *)buf->ptr; 319f540a430SEd Maste 320f540a430SEd Maste memset(&expected, 0, sizeof(expected)); 321f540a430SEd Maste expected.magic = TPM_MAGIC; 322f540a430SEd Maste expected.type = TPM_ST_CERTIFY; 323f540a430SEd Maste expected.signer = actual->signer; 324f540a430SEd Maste expected.signer.size = sizeof(expected.signer.alg) + 325f540a430SEd Maste sizeof(expected.signer.body); 326f540a430SEd Maste expected.data = signed_data; 327f540a430SEd Maste expected.clock = actual->clock; 328f540a430SEd Maste expected.clock.safe = 1; 329f540a430SEd Maste expected.fwversion = actual->fwversion; 330f540a430SEd Maste expected.name = signed_name; 331f540a430SEd Maste expected.qual_name = actual->qual_name; 332f540a430SEd Maste bswap_sha1_certinfo(&expected); 333f540a430SEd Maste 334f540a430SEd Maste ok = timingsafe_bcmp(&expected, actual, sizeof(expected)); 335f540a430SEd Maste fail: 336f540a430SEd Maste explicit_bzero(&expected, sizeof(expected)); 337f540a430SEd Maste explicit_bzero(&signed_data, sizeof(signed_data)); 338f540a430SEd Maste explicit_bzero(&signed_name, sizeof(signed_name)); 339f540a430SEd Maste 340f540a430SEd Maste return ok != 0 ? -1 : 0; 341f540a430SEd Maste } 342f540a430SEd Maste 343f540a430SEd Maste int 344f540a430SEd Maste fido_get_signed_hash_tpm(fido_blob_t *dgst, const fido_blob_t *clientdata_hash, 345f540a430SEd Maste const fido_blob_t *authdata_raw, const fido_attstmt_t *attstmt, 346f540a430SEd Maste const fido_attcred_t *attcred) 347f540a430SEd Maste { 348f540a430SEd Maste const fido_blob_t *pubarea = &attstmt->pubarea; 349f540a430SEd Maste const fido_blob_t *certinfo = &attstmt->certinfo; 350f540a430SEd Maste 351*3e696dfbSEd Maste if (attstmt->alg != COSE_RS1) { 352*3e696dfbSEd Maste fido_log_debug("%s: unsupported alg %d", __func__, 353*3e696dfbSEd Maste attstmt->alg); 354f540a430SEd Maste return -1; 355f540a430SEd Maste } 356f540a430SEd Maste 357*3e696dfbSEd Maste switch (attcred->type) { 358*3e696dfbSEd Maste case COSE_ES256: 359*3e696dfbSEd Maste if (check_es256_pubarea(pubarea, &attcred->pubkey.es256) < 0) { 360*3e696dfbSEd Maste fido_log_debug("%s: check_es256_pubarea", __func__); 361*3e696dfbSEd Maste return -1; 362*3e696dfbSEd Maste } 363*3e696dfbSEd Maste break; 364*3e696dfbSEd Maste case COSE_RS256: 365*3e696dfbSEd Maste if (check_rs256_pubarea(pubarea, &attcred->pubkey.rs256) < 0) { 366*3e696dfbSEd Maste fido_log_debug("%s: check_rs256_pubarea", __func__); 367*3e696dfbSEd Maste return -1; 368*3e696dfbSEd Maste } 369*3e696dfbSEd Maste break; 370*3e696dfbSEd Maste default: 371*3e696dfbSEd Maste fido_log_debug("%s: unsupported type %d", __func__, 372*3e696dfbSEd Maste attcred->type); 373f540a430SEd Maste return -1; 374f540a430SEd Maste } 375f540a430SEd Maste 376f540a430SEd Maste if (check_sha1_certinfo(certinfo, clientdata_hash, authdata_raw, 377f540a430SEd Maste pubarea) < 0) { 378f540a430SEd Maste fido_log_debug("%s: check_sha1_certinfo", __func__); 379f540a430SEd Maste return -1; 380f540a430SEd Maste } 381f540a430SEd Maste 382f540a430SEd Maste if (dgst->len < SHA_DIGEST_LENGTH || 383f540a430SEd Maste SHA1(certinfo->ptr, certinfo->len, dgst->ptr) != dgst->ptr) { 384f540a430SEd Maste fido_log_debug("%s: sha1", __func__); 385f540a430SEd Maste return -1; 386f540a430SEd Maste } 387f540a430SEd Maste dgst->len = SHA_DIGEST_LENGTH; 388f540a430SEd Maste 389f540a430SEd Maste return 0; 390f540a430SEd Maste } 391