xref: /freebsd/contrib/libfido2/src/rs1.c (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1 /*
2  * Copyright (c) 2021 Yubico AB. All rights reserved.
3  * Use of this source code is governed by a BSD-style
4  * license that can be found in the LICENSE file.
5  * SPDX-License-Identifier: BSD-2-Clause
6  */
7 
8 #include <openssl/rsa.h>
9 #include <openssl/obj_mac.h>
10 
11 #include "fido.h"
12 
13 #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050200fL
14 static EVP_MD *
15 rs1_get_EVP_MD(void)
16 {
17 	const EVP_MD *from;
18 	EVP_MD *to = NULL;
19 
20 	if ((from = EVP_sha1()) != NULL && (to = malloc(sizeof(*to))) != NULL)
21 		memcpy(to, from, sizeof(*to));
22 
23 	return (to);
24 }
25 
26 static void
27 rs1_free_EVP_MD(EVP_MD *md)
28 {
29 	freezero(md, sizeof(*md));
30 }
31 #elif OPENSSL_VERSION_NUMBER >= 0x30000000
32 static EVP_MD *
33 rs1_get_EVP_MD(void)
34 {
35 	return (EVP_MD_fetch(NULL, "SHA-1", NULL));
36 }
37 
38 static void
39 rs1_free_EVP_MD(EVP_MD *md)
40 {
41 	EVP_MD_free(md);
42 }
43 #else
44 static EVP_MD *
45 rs1_get_EVP_MD(void)
46 {
47 	const EVP_MD *md;
48 
49 	if ((md = EVP_sha1()) == NULL)
50 		return (NULL);
51 
52 	return (EVP_MD_meth_dup(md));
53 }
54 
55 static void
56 rs1_free_EVP_MD(EVP_MD *md)
57 {
58 	EVP_MD_meth_free(md);
59 }
60 #endif /* LIBRESSL_VERSION_NUMBER */
61 
62 int
63 rs1_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey,
64     const fido_blob_t *sig)
65 {
66 	EVP_PKEY_CTX	*pctx = NULL;
67 	EVP_MD		*md = NULL;
68 	int		 ok = -1;
69 
70 	if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
71 		fido_log_debug("%s: EVP_PKEY_base_id", __func__);
72 		goto fail;
73 	}
74 
75 	if ((md = rs1_get_EVP_MD()) == NULL) {
76 		fido_log_debug("%s: rs1_get_EVP_MD", __func__);
77 		goto fail;
78 	}
79 
80 	if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL ||
81 	    EVP_PKEY_verify_init(pctx) != 1 ||
82 	    EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) != 1 ||
83 	    EVP_PKEY_CTX_set_signature_md(pctx, md) != 1) {
84 		fido_log_debug("%s: EVP_PKEY_CTX", __func__);
85 		goto fail;
86 	}
87 
88 	if (EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr,
89 	    dgst->len) != 1) {
90 		fido_log_debug("%s: EVP_PKEY_verify", __func__);
91 		goto fail;
92 	}
93 
94 	ok = 0;
95 fail:
96 	EVP_PKEY_CTX_free(pctx);
97 	rs1_free_EVP_MD(md);
98 
99 	return (ok);
100 }
101