1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * RSA key extract helper
4 *
5 * Copyright (c) 2015, Intel Corporation
6 * Authors: Tadeusz Struk <tadeusz.struk@intel.com>
7 */
8#ifndef __UBOOT__
9#include <linux/compat.h>
10#include <linux/kernel.h>
11#include <linux/export.h>
12#endif
13#include <linux/err.h>
14#ifndef __UBOOT__
15#include <linux/fips.h>
16#endif
17#include <crypto/internal/rsa.h>
18#include <linux/printk.h>
19#include "rsapubkey.asn1.h"
20#ifndef __UBOOT__
21#include "rsaprivkey.asn1.h"
22#endif
23
24int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
25	      const void *value, size_t vlen)
26{
27	struct rsa_key *key = context;
28#ifndef __UBOOT__
29	const u8 *ptr = value;
30	size_t n_sz = vlen;
31#endif
32
33	/* invalid key provided */
34	if (!value || !vlen)
35		return -EINVAL;
36
37#ifndef __UBOOT__
38	if (fips_enabled) {
39		while (n_sz && !*ptr) {
40			ptr++;
41			n_sz--;
42		}
43
44		/* In FIPS mode only allow key size 2K and higher */
45		if (n_sz < 256) {
46			pr_err("RSA: key size not allowed in FIPS mode\n");
47			return -EINVAL;
48		}
49	}
50#endif
51
52	key->n = value;
53	key->n_sz = vlen;
54
55	return 0;
56}
57
58int rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
59	      const void *value, size_t vlen)
60{
61	struct rsa_key *key = context;
62
63	/* invalid key provided */
64	if (!value || !key->n_sz || !vlen || vlen > key->n_sz)
65		return -EINVAL;
66
67	key->e = value;
68	key->e_sz = vlen;
69
70	return 0;
71}
72
73int rsa_get_d(void *context, size_t hdrlen, unsigned char tag,
74	      const void *value, size_t vlen)
75{
76	struct rsa_key *key = context;
77
78	/* invalid key provided */
79	if (!value || !key->n_sz || !vlen || vlen > key->n_sz)
80		return -EINVAL;
81
82	key->d = value;
83	key->d_sz = vlen;
84
85	return 0;
86}
87
88int rsa_get_p(void *context, size_t hdrlen, unsigned char tag,
89	      const void *value, size_t vlen)
90{
91	struct rsa_key *key = context;
92
93	/* invalid key provided */
94	if (!value || !vlen || vlen > key->n_sz)
95		return -EINVAL;
96
97	key->p = value;
98	key->p_sz = vlen;
99
100	return 0;
101}
102
103int rsa_get_q(void *context, size_t hdrlen, unsigned char tag,
104	      const void *value, size_t vlen)
105{
106	struct rsa_key *key = context;
107
108	/* invalid key provided */
109	if (!value || !vlen || vlen > key->n_sz)
110		return -EINVAL;
111
112	key->q = value;
113	key->q_sz = vlen;
114
115	return 0;
116}
117
118int rsa_get_dp(void *context, size_t hdrlen, unsigned char tag,
119	       const void *value, size_t vlen)
120{
121	struct rsa_key *key = context;
122
123	/* invalid key provided */
124	if (!value || !vlen || vlen > key->n_sz)
125		return -EINVAL;
126
127	key->dp = value;
128	key->dp_sz = vlen;
129
130	return 0;
131}
132
133int rsa_get_dq(void *context, size_t hdrlen, unsigned char tag,
134	       const void *value, size_t vlen)
135{
136	struct rsa_key *key = context;
137
138	/* invalid key provided */
139	if (!value || !vlen || vlen > key->n_sz)
140		return -EINVAL;
141
142	key->dq = value;
143	key->dq_sz = vlen;
144
145	return 0;
146}
147
148int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag,
149		 const void *value, size_t vlen)
150{
151	struct rsa_key *key = context;
152
153	/* invalid key provided */
154	if (!value || !vlen || vlen > key->n_sz)
155		return -EINVAL;
156
157	key->qinv = value;
158	key->qinv_sz = vlen;
159
160	return 0;
161}
162
163/**
164 * rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
165 *                       provided struct rsa_key, pointers to the raw key as is,
166 *                       so that the caller can copy it or MPI parse it, etc.
167 *
168 * @rsa_key:	struct rsa_key key representation
169 * @key:	key in BER format
170 * @key_len:	length of key
171 *
172 * Return:	0 on success or error code in case of error
173 */
174int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
175		      unsigned int key_len)
176{
177	return asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
178}
179EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
180
181#ifndef __UBOOT__
182/**
183 * rsa_parse_priv_key() - decodes the BER encoded buffer and stores in the
184 *                        provided struct rsa_key, pointers to the raw key
185 *                        as is, so that the caller can copy it or MPI parse it,
186 *                        etc.
187 *
188 * @rsa_key:	struct rsa_key key representation
189 * @key:	key in BER format
190 * @key_len:	length of key
191 *
192 * Return:	0 on success or error code in case of error
193 */
194int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
195		       unsigned int key_len)
196{
197	return asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
198}
199EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
200#endif
201