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