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