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