1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2013, Google Inc.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include "mkimage.h"
8*4882a593Smuzhiyun #include <stdio.h>
9*4882a593Smuzhiyun #include <string.h>
10*4882a593Smuzhiyun #include <image.h>
11*4882a593Smuzhiyun #include <time.h>
12*4882a593Smuzhiyun #include <generated/autoconf.h>
13*4882a593Smuzhiyun #include <openssl/bn.h>
14*4882a593Smuzhiyun #include <openssl/rsa.h>
15*4882a593Smuzhiyun #include <openssl/pem.h>
16*4882a593Smuzhiyun #include <openssl/err.h>
17*4882a593Smuzhiyun #include <openssl/ssl.h>
18*4882a593Smuzhiyun #include <openssl/evp.h>
19*4882a593Smuzhiyun #include <openssl/engine.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #if OPENSSL_VERSION_NUMBER >= 0x10000000L
22*4882a593Smuzhiyun #define HAVE_ERR_REMOVE_THREAD_STATE
23*4882a593Smuzhiyun #endif
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #if OPENSSL_VERSION_NUMBER < 0x10100000L
RSA_get0_key(const RSA * r,const BIGNUM ** n,const BIGNUM ** e,const BIGNUM ** d)26*4882a593Smuzhiyun static void RSA_get0_key(const RSA *r,
27*4882a593Smuzhiyun const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun if (n != NULL)
30*4882a593Smuzhiyun *n = r->n;
31*4882a593Smuzhiyun if (e != NULL)
32*4882a593Smuzhiyun *e = r->e;
33*4882a593Smuzhiyun if (d != NULL)
34*4882a593Smuzhiyun *d = r->d;
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun
rsa_err(const char * msg)38*4882a593Smuzhiyun static int rsa_err(const char *msg)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun unsigned long sslErr = ERR_get_error();
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun fprintf(stderr, "%s", msg);
43*4882a593Smuzhiyun fprintf(stderr, ": %s\n",
44*4882a593Smuzhiyun ERR_error_string(sslErr, 0));
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun return -1;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun /**
50*4882a593Smuzhiyun * rsa_pem_get_pub_key() - read a public key from a .crt file
51*4882a593Smuzhiyun *
52*4882a593Smuzhiyun * @keydir: Directory containins the key
53*4882a593Smuzhiyun * @name Name of key file (will have a .crt extension)
54*4882a593Smuzhiyun * @rsap Returns RSA object, or NULL on failure
55*4882a593Smuzhiyun * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL)
56*4882a593Smuzhiyun */
rsa_pem_get_pub_key(const char * keydir,const char * name,RSA ** rsap)57*4882a593Smuzhiyun static int rsa_pem_get_pub_key(const char *keydir, const char *name, RSA **rsap)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun char path[1024];
60*4882a593Smuzhiyun EVP_PKEY *key;
61*4882a593Smuzhiyun X509 *cert;
62*4882a593Smuzhiyun RSA *rsa;
63*4882a593Smuzhiyun FILE *f;
64*4882a593Smuzhiyun int ret;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun *rsap = NULL;
67*4882a593Smuzhiyun snprintf(path, sizeof(path), "%s/%s.crt", keydir, name);
68*4882a593Smuzhiyun f = fopen(path, "r");
69*4882a593Smuzhiyun if (!f) {
70*4882a593Smuzhiyun fprintf(stderr, "Couldn't open RSA certificate: '%s': %s\n",
71*4882a593Smuzhiyun path, strerror(errno));
72*4882a593Smuzhiyun return -EACCES;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* Read the certificate */
76*4882a593Smuzhiyun cert = NULL;
77*4882a593Smuzhiyun if (!PEM_read_X509(f, &cert, NULL, NULL)) {
78*4882a593Smuzhiyun rsa_err("Couldn't read certificate");
79*4882a593Smuzhiyun ret = -EINVAL;
80*4882a593Smuzhiyun goto err_cert;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun /* Get the public key from the certificate. */
84*4882a593Smuzhiyun key = X509_get_pubkey(cert);
85*4882a593Smuzhiyun if (!key) {
86*4882a593Smuzhiyun rsa_err("Couldn't read public key\n");
87*4882a593Smuzhiyun ret = -EINVAL;
88*4882a593Smuzhiyun goto err_pubkey;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* Convert to a RSA_style key. */
92*4882a593Smuzhiyun rsa = EVP_PKEY_get1_RSA(key);
93*4882a593Smuzhiyun if (!rsa) {
94*4882a593Smuzhiyun rsa_err("Couldn't convert to a RSA style key");
95*4882a593Smuzhiyun ret = -EINVAL;
96*4882a593Smuzhiyun goto err_rsa;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun fclose(f);
99*4882a593Smuzhiyun EVP_PKEY_free(key);
100*4882a593Smuzhiyun X509_free(cert);
101*4882a593Smuzhiyun *rsap = rsa;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun return 0;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun err_rsa:
106*4882a593Smuzhiyun EVP_PKEY_free(key);
107*4882a593Smuzhiyun err_pubkey:
108*4882a593Smuzhiyun X509_free(cert);
109*4882a593Smuzhiyun err_cert:
110*4882a593Smuzhiyun fclose(f);
111*4882a593Smuzhiyun return ret;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun /**
115*4882a593Smuzhiyun * rsa_engine_get_pub_key() - read a public key from given engine
116*4882a593Smuzhiyun *
117*4882a593Smuzhiyun * @keydir: Key prefix
118*4882a593Smuzhiyun * @name Name of key
119*4882a593Smuzhiyun * @engine Engine to use
120*4882a593Smuzhiyun * @rsap Returns RSA object, or NULL on failure
121*4882a593Smuzhiyun * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL)
122*4882a593Smuzhiyun */
rsa_engine_get_pub_key(const char * keydir,const char * name,ENGINE * engine,RSA ** rsap)123*4882a593Smuzhiyun static int rsa_engine_get_pub_key(const char *keydir, const char *name,
124*4882a593Smuzhiyun ENGINE *engine, RSA **rsap)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun const char *engine_id;
127*4882a593Smuzhiyun char key_id[1024];
128*4882a593Smuzhiyun EVP_PKEY *key;
129*4882a593Smuzhiyun RSA *rsa;
130*4882a593Smuzhiyun int ret;
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun *rsap = NULL;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun engine_id = ENGINE_get_id(engine);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun if (engine_id && !strcmp(engine_id, "pkcs11")) {
137*4882a593Smuzhiyun if (keydir)
138*4882a593Smuzhiyun snprintf(key_id, sizeof(key_id),
139*4882a593Smuzhiyun "pkcs11:%s;object=%s;type=public",
140*4882a593Smuzhiyun keydir, name);
141*4882a593Smuzhiyun else
142*4882a593Smuzhiyun snprintf(key_id, sizeof(key_id),
143*4882a593Smuzhiyun "pkcs11:object=%s;type=public",
144*4882a593Smuzhiyun name);
145*4882a593Smuzhiyun } else {
146*4882a593Smuzhiyun fprintf(stderr, "Engine not supported\n");
147*4882a593Smuzhiyun return -ENOTSUP;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun key = ENGINE_load_public_key(engine, key_id, NULL, NULL);
151*4882a593Smuzhiyun if (!key)
152*4882a593Smuzhiyun return rsa_err("Failure loading public key from engine");
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun /* Convert to a RSA_style key. */
155*4882a593Smuzhiyun rsa = EVP_PKEY_get1_RSA(key);
156*4882a593Smuzhiyun if (!rsa) {
157*4882a593Smuzhiyun rsa_err("Couldn't convert to a RSA style key");
158*4882a593Smuzhiyun ret = -EINVAL;
159*4882a593Smuzhiyun goto err_rsa;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun EVP_PKEY_free(key);
163*4882a593Smuzhiyun *rsap = rsa;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun return 0;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun err_rsa:
168*4882a593Smuzhiyun EVP_PKEY_free(key);
169*4882a593Smuzhiyun return ret;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /**
173*4882a593Smuzhiyun * rsa_get_pub_key() - read a public key
174*4882a593Smuzhiyun *
175*4882a593Smuzhiyun * @keydir: Directory containing the key (PEM file) or key prefix (engine)
176*4882a593Smuzhiyun * @name Name of key file (will have a .crt extension)
177*4882a593Smuzhiyun * @engine Engine to use
178*4882a593Smuzhiyun * @rsap Returns RSA object, or NULL on failure
179*4882a593Smuzhiyun * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL)
180*4882a593Smuzhiyun */
rsa_get_pub_key(const char * keydir,const char * name,ENGINE * engine,RSA ** rsap)181*4882a593Smuzhiyun static int rsa_get_pub_key(const char *keydir, const char *name,
182*4882a593Smuzhiyun ENGINE *engine, RSA **rsap)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun if (engine)
185*4882a593Smuzhiyun return rsa_engine_get_pub_key(keydir, name, engine, rsap);
186*4882a593Smuzhiyun return rsa_pem_get_pub_key(keydir, name, rsap);
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun /**
190*4882a593Smuzhiyun * rsa_pem_get_priv_key() - read a private key from a .key file
191*4882a593Smuzhiyun *
192*4882a593Smuzhiyun * @keydir: Directory containing the key
193*4882a593Smuzhiyun * @name Name of key file (will have a .key extension)
194*4882a593Smuzhiyun * @rsap Returns RSA object, or NULL on failure
195*4882a593Smuzhiyun * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL)
196*4882a593Smuzhiyun */
rsa_pem_get_priv_key(const char * keydir,const char * name,RSA ** rsap)197*4882a593Smuzhiyun static int rsa_pem_get_priv_key(const char *keydir, const char *name,
198*4882a593Smuzhiyun RSA **rsap)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun char path[1024];
201*4882a593Smuzhiyun RSA *rsa;
202*4882a593Smuzhiyun FILE *f;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun *rsap = NULL;
205*4882a593Smuzhiyun snprintf(path, sizeof(path), "%s/%s.key", keydir, name);
206*4882a593Smuzhiyun f = fopen(path, "r");
207*4882a593Smuzhiyun if (!f) {
208*4882a593Smuzhiyun fprintf(stderr, "Couldn't open RSA private key: '%s': %s\n",
209*4882a593Smuzhiyun path, strerror(errno));
210*4882a593Smuzhiyun return -ENOENT;
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun rsa = PEM_read_RSAPrivateKey(f, 0, NULL, path);
214*4882a593Smuzhiyun if (!rsa) {
215*4882a593Smuzhiyun rsa_err("Failure reading private key");
216*4882a593Smuzhiyun fclose(f);
217*4882a593Smuzhiyun return -EPROTO;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun fclose(f);
220*4882a593Smuzhiyun *rsap = rsa;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun return 0;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /**
226*4882a593Smuzhiyun * rsa_engine_get_priv_key() - read a private key from given engine
227*4882a593Smuzhiyun *
228*4882a593Smuzhiyun * @keydir: Key prefix
229*4882a593Smuzhiyun * @name Name of key
230*4882a593Smuzhiyun * @engine Engine to use
231*4882a593Smuzhiyun * @rsap Returns RSA object, or NULL on failure
232*4882a593Smuzhiyun * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL)
233*4882a593Smuzhiyun */
rsa_engine_get_priv_key(const char * keydir,const char * name,ENGINE * engine,RSA ** rsap)234*4882a593Smuzhiyun static int rsa_engine_get_priv_key(const char *keydir, const char *name,
235*4882a593Smuzhiyun ENGINE *engine, RSA **rsap)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun const char *engine_id;
238*4882a593Smuzhiyun char key_id[1024];
239*4882a593Smuzhiyun EVP_PKEY *key;
240*4882a593Smuzhiyun RSA *rsa;
241*4882a593Smuzhiyun int ret;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun *rsap = NULL;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun engine_id = ENGINE_get_id(engine);
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun if (engine_id && !strcmp(engine_id, "pkcs11")) {
248*4882a593Smuzhiyun if (keydir)
249*4882a593Smuzhiyun snprintf(key_id, sizeof(key_id),
250*4882a593Smuzhiyun "pkcs11:%s;object=%s;type=private",
251*4882a593Smuzhiyun keydir, name);
252*4882a593Smuzhiyun else
253*4882a593Smuzhiyun snprintf(key_id, sizeof(key_id),
254*4882a593Smuzhiyun "pkcs11:object=%s;type=private",
255*4882a593Smuzhiyun name);
256*4882a593Smuzhiyun } else {
257*4882a593Smuzhiyun fprintf(stderr, "Engine not supported\n");
258*4882a593Smuzhiyun return -ENOTSUP;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun key = ENGINE_load_private_key(engine, key_id, NULL, NULL);
262*4882a593Smuzhiyun if (!key)
263*4882a593Smuzhiyun return rsa_err("Failure loading private key from engine");
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun /* Convert to a RSA_style key. */
266*4882a593Smuzhiyun rsa = EVP_PKEY_get1_RSA(key);
267*4882a593Smuzhiyun if (!rsa) {
268*4882a593Smuzhiyun rsa_err("Couldn't convert to a RSA style key");
269*4882a593Smuzhiyun ret = -EINVAL;
270*4882a593Smuzhiyun goto err_rsa;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun EVP_PKEY_free(key);
274*4882a593Smuzhiyun *rsap = rsa;
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun return 0;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun err_rsa:
279*4882a593Smuzhiyun EVP_PKEY_free(key);
280*4882a593Smuzhiyun return ret;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun /**
284*4882a593Smuzhiyun * rsa_get_priv_key() - read a private key
285*4882a593Smuzhiyun *
286*4882a593Smuzhiyun * @keydir: Directory containing the key (PEM file) or key prefix (engine)
287*4882a593Smuzhiyun * @name Name of key
288*4882a593Smuzhiyun * @engine Engine to use for signing
289*4882a593Smuzhiyun * @rsap Returns RSA object, or NULL on failure
290*4882a593Smuzhiyun * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL)
291*4882a593Smuzhiyun */
rsa_get_priv_key(const char * keydir,const char * name,ENGINE * engine,RSA ** rsap)292*4882a593Smuzhiyun static int rsa_get_priv_key(const char *keydir, const char *name,
293*4882a593Smuzhiyun ENGINE *engine, RSA **rsap)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun if (engine)
296*4882a593Smuzhiyun return rsa_engine_get_priv_key(keydir, name, engine, rsap);
297*4882a593Smuzhiyun return rsa_pem_get_priv_key(keydir, name, rsap);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
rsa_init(void)300*4882a593Smuzhiyun static int rsa_init(void)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun int ret;
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun #if OPENSSL_VERSION_NUMBER < 0x10100000L
305*4882a593Smuzhiyun ret = SSL_library_init();
306*4882a593Smuzhiyun #else
307*4882a593Smuzhiyun ret = OPENSSL_init_ssl(0, NULL);
308*4882a593Smuzhiyun #endif
309*4882a593Smuzhiyun if (!ret) {
310*4882a593Smuzhiyun fprintf(stderr, "Failure to init SSL library\n");
311*4882a593Smuzhiyun return -1;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun #if OPENSSL_VERSION_NUMBER < 0x10100000L
314*4882a593Smuzhiyun SSL_load_error_strings();
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun OpenSSL_add_all_algorithms();
317*4882a593Smuzhiyun OpenSSL_add_all_digests();
318*4882a593Smuzhiyun OpenSSL_add_all_ciphers();
319*4882a593Smuzhiyun #endif
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun return 0;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
rsa_engine_init(const char * engine_id,ENGINE ** pe)324*4882a593Smuzhiyun static int rsa_engine_init(const char *engine_id, ENGINE **pe)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun ENGINE *e;
327*4882a593Smuzhiyun int ret;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun ENGINE_load_builtin_engines();
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun e = ENGINE_by_id(engine_id);
332*4882a593Smuzhiyun if (!e) {
333*4882a593Smuzhiyun fprintf(stderr, "Engine isn't available\n");
334*4882a593Smuzhiyun ret = -1;
335*4882a593Smuzhiyun goto err_engine_by_id;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun if (!ENGINE_init(e)) {
339*4882a593Smuzhiyun fprintf(stderr, "Couldn't initialize engine\n");
340*4882a593Smuzhiyun ret = -1;
341*4882a593Smuzhiyun goto err_engine_init;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun if (!ENGINE_set_default_RSA(e)) {
345*4882a593Smuzhiyun fprintf(stderr, "Couldn't set engine as default for RSA\n");
346*4882a593Smuzhiyun ret = -1;
347*4882a593Smuzhiyun goto err_set_rsa;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun *pe = e;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun return 0;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun err_set_rsa:
355*4882a593Smuzhiyun ENGINE_finish(e);
356*4882a593Smuzhiyun err_engine_init:
357*4882a593Smuzhiyun ENGINE_free(e);
358*4882a593Smuzhiyun err_engine_by_id:
359*4882a593Smuzhiyun #if OPENSSL_VERSION_NUMBER < 0x10100000L
360*4882a593Smuzhiyun ENGINE_cleanup();
361*4882a593Smuzhiyun #endif
362*4882a593Smuzhiyun return ret;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
rsa_remove(void)365*4882a593Smuzhiyun static void rsa_remove(void)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun #if OPENSSL_VERSION_NUMBER < 0x10100000L
368*4882a593Smuzhiyun CRYPTO_cleanup_all_ex_data();
369*4882a593Smuzhiyun ERR_free_strings();
370*4882a593Smuzhiyun #ifdef HAVE_ERR_REMOVE_THREAD_STATE
371*4882a593Smuzhiyun ERR_remove_thread_state(NULL);
372*4882a593Smuzhiyun #else
373*4882a593Smuzhiyun ERR_remove_state(0);
374*4882a593Smuzhiyun #endif
375*4882a593Smuzhiyun EVP_cleanup();
376*4882a593Smuzhiyun #endif
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
rsa_engine_remove(ENGINE * e)379*4882a593Smuzhiyun static void rsa_engine_remove(ENGINE *e)
380*4882a593Smuzhiyun {
381*4882a593Smuzhiyun if (e) {
382*4882a593Smuzhiyun ENGINE_finish(e);
383*4882a593Smuzhiyun ENGINE_free(e);
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /*
388*4882a593Smuzhiyun * With this data2sign.bin, we can provide it to who real holds the RAS-private
389*4882a593Smuzhiyun * key to sign current fit image. Then we replace the signature in fit image
390*4882a593Smuzhiyun * with a valid one.
391*4882a593Smuzhiyun */
gen_data2sign(const struct image_region region[],int region_count)392*4882a593Smuzhiyun static int gen_data2sign(const struct image_region region[], int region_count)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun char *file = "data2sign.bin";
395*4882a593Smuzhiyun FILE *fd;
396*4882a593Smuzhiyun int i;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun fd = fopen(file, "wb");
399*4882a593Smuzhiyun if (!fd) {
400*4882a593Smuzhiyun fprintf(stderr, "Failed to create %s: %s\n",
401*4882a593Smuzhiyun file, strerror(errno));
402*4882a593Smuzhiyun return -ENOENT;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun for (i = 0; i < region_count; i++)
406*4882a593Smuzhiyun fwrite(region[i].data, region[i].size, 1, fd);
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun fclose(fd);
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun return 0;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
rsa_sign_with_key(RSA * rsa,struct padding_algo * padding_algo,struct checksum_algo * checksum_algo,const struct image_region region[],int region_count,uint8_t ** sigp,uint * sig_size)413*4882a593Smuzhiyun static int rsa_sign_with_key(RSA *rsa, struct padding_algo *padding_algo,
414*4882a593Smuzhiyun struct checksum_algo *checksum_algo,
415*4882a593Smuzhiyun const struct image_region region[], int region_count,
416*4882a593Smuzhiyun uint8_t **sigp, uint *sig_size)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun EVP_PKEY *key;
419*4882a593Smuzhiyun EVP_PKEY_CTX *ckey;
420*4882a593Smuzhiyun EVP_MD_CTX *context;
421*4882a593Smuzhiyun int ret = 0;
422*4882a593Smuzhiyun size_t size;
423*4882a593Smuzhiyun uint8_t *sig;
424*4882a593Smuzhiyun int i;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun key = EVP_PKEY_new();
427*4882a593Smuzhiyun if (!key)
428*4882a593Smuzhiyun return rsa_err("EVP_PKEY object creation failed");
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun if (!EVP_PKEY_set1_RSA(key, rsa)) {
431*4882a593Smuzhiyun ret = rsa_err("EVP key setup failed");
432*4882a593Smuzhiyun goto err_set;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun size = EVP_PKEY_size(key);
436*4882a593Smuzhiyun sig = malloc(size);
437*4882a593Smuzhiyun if (!sig) {
438*4882a593Smuzhiyun fprintf(stderr, "Out of memory for signature (%zu bytes)\n",
439*4882a593Smuzhiyun size);
440*4882a593Smuzhiyun ret = -ENOMEM;
441*4882a593Smuzhiyun goto err_alloc;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun context = EVP_MD_CTX_create();
445*4882a593Smuzhiyun if (!context) {
446*4882a593Smuzhiyun ret = rsa_err("EVP context creation failed");
447*4882a593Smuzhiyun goto err_create;
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun EVP_MD_CTX_init(context);
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun ckey = EVP_PKEY_CTX_new(key, NULL);
452*4882a593Smuzhiyun if (!ckey) {
453*4882a593Smuzhiyun ret = rsa_err("EVP key context creation failed");
454*4882a593Smuzhiyun goto err_create;
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun if (EVP_DigestSignInit(context, &ckey,
458*4882a593Smuzhiyun checksum_algo->calculate_sign(),
459*4882a593Smuzhiyun NULL, key) <= 0) {
460*4882a593Smuzhiyun ret = rsa_err("Signer setup failed");
461*4882a593Smuzhiyun goto err_sign;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun #ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
465*4882a593Smuzhiyun if (padding_algo && !strcmp(padding_algo->name, "pss")) {
466*4882a593Smuzhiyun if (EVP_PKEY_CTX_set_rsa_padding(ckey,
467*4882a593Smuzhiyun RSA_PKCS1_PSS_PADDING) <= 0) {
468*4882a593Smuzhiyun ret = rsa_err("Signer padding setup failed");
469*4882a593Smuzhiyun goto err_sign;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun #endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun for (i = 0; i < region_count; i++) {
475*4882a593Smuzhiyun if (!EVP_DigestSignUpdate(context, region[i].data,
476*4882a593Smuzhiyun region[i].size)) {
477*4882a593Smuzhiyun ret = rsa_err("Signing data failed");
478*4882a593Smuzhiyun goto err_sign;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun if (!EVP_DigestSignFinal(context, sig, &size)) {
483*4882a593Smuzhiyun ret = rsa_err("Could not obtain signature");
484*4882a593Smuzhiyun goto err_sign;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
488*4882a593Smuzhiyun (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
489*4882a593Smuzhiyun EVP_MD_CTX_cleanup(context);
490*4882a593Smuzhiyun #else
491*4882a593Smuzhiyun EVP_MD_CTX_reset(context);
492*4882a593Smuzhiyun #endif
493*4882a593Smuzhiyun EVP_MD_CTX_destroy(context);
494*4882a593Smuzhiyun EVP_PKEY_free(key);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun debug("Got signature: %d bytes, expected %zu\n", *sig_size, size);
497*4882a593Smuzhiyun *sigp = sig;
498*4882a593Smuzhiyun *sig_size = size;
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun gen_data2sign(region, region_count);
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun return 0;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun err_sign:
505*4882a593Smuzhiyun EVP_MD_CTX_destroy(context);
506*4882a593Smuzhiyun err_create:
507*4882a593Smuzhiyun free(sig);
508*4882a593Smuzhiyun err_alloc:
509*4882a593Smuzhiyun err_set:
510*4882a593Smuzhiyun EVP_PKEY_free(key);
511*4882a593Smuzhiyun return ret;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun
rsa_sign(struct image_sign_info * info,const struct image_region region[],int region_count,uint8_t ** sigp,uint * sig_len)514*4882a593Smuzhiyun int rsa_sign(struct image_sign_info *info,
515*4882a593Smuzhiyun const struct image_region region[], int region_count,
516*4882a593Smuzhiyun uint8_t **sigp, uint *sig_len)
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun RSA *rsa;
519*4882a593Smuzhiyun ENGINE *e = NULL;
520*4882a593Smuzhiyun int ret;
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun ret = rsa_init();
523*4882a593Smuzhiyun if (ret)
524*4882a593Smuzhiyun return ret;
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun if (info->engine_id) {
527*4882a593Smuzhiyun ret = rsa_engine_init(info->engine_id, &e);
528*4882a593Smuzhiyun if (ret)
529*4882a593Smuzhiyun goto err_engine;
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun ret = rsa_get_priv_key(info->keydir, info->keyname, e, &rsa);
533*4882a593Smuzhiyun if (ret)
534*4882a593Smuzhiyun goto err_priv;
535*4882a593Smuzhiyun ret = rsa_sign_with_key(rsa, info->padding, info->checksum, region,
536*4882a593Smuzhiyun region_count, sigp, sig_len);
537*4882a593Smuzhiyun if (ret)
538*4882a593Smuzhiyun goto err_sign;
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun RSA_free(rsa);
541*4882a593Smuzhiyun if (info->engine_id)
542*4882a593Smuzhiyun rsa_engine_remove(e);
543*4882a593Smuzhiyun rsa_remove();
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun return ret;
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun err_sign:
548*4882a593Smuzhiyun RSA_free(rsa);
549*4882a593Smuzhiyun err_priv:
550*4882a593Smuzhiyun if (info->engine_id)
551*4882a593Smuzhiyun rsa_engine_remove(e);
552*4882a593Smuzhiyun err_engine:
553*4882a593Smuzhiyun rsa_remove();
554*4882a593Smuzhiyun return ret;
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun /*
558*4882a593Smuzhiyun * rsa_get_exponent(): - Get the public exponent from an RSA key
559*4882a593Smuzhiyun */
rsa_get_exponent(RSA * key,uint64_t * e)560*4882a593Smuzhiyun static int rsa_get_exponent(RSA *key, uint64_t *e)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun int ret;
563*4882a593Smuzhiyun BIGNUM *bn_te;
564*4882a593Smuzhiyun const BIGNUM *key_e;
565*4882a593Smuzhiyun uint64_t te;
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun ret = -EINVAL;
568*4882a593Smuzhiyun bn_te = NULL;
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun if (!e)
571*4882a593Smuzhiyun goto cleanup;
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun RSA_get0_key(key, NULL, &key_e, NULL);
574*4882a593Smuzhiyun if (BN_num_bits(key_e) > 64)
575*4882a593Smuzhiyun goto cleanup;
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun *e = BN_get_word(key_e);
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun if (BN_num_bits(key_e) < 33) {
580*4882a593Smuzhiyun ret = 0;
581*4882a593Smuzhiyun goto cleanup;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun bn_te = BN_dup(key_e);
585*4882a593Smuzhiyun if (!bn_te)
586*4882a593Smuzhiyun goto cleanup;
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun if (!BN_rshift(bn_te, bn_te, 32))
589*4882a593Smuzhiyun goto cleanup;
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun if (!BN_mask_bits(bn_te, 32))
592*4882a593Smuzhiyun goto cleanup;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun te = BN_get_word(bn_te);
595*4882a593Smuzhiyun te <<= 32;
596*4882a593Smuzhiyun *e |= te;
597*4882a593Smuzhiyun ret = 0;
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun cleanup:
600*4882a593Smuzhiyun if (bn_te)
601*4882a593Smuzhiyun BN_free(bn_te);
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun return ret;
604*4882a593Smuzhiyun }
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun /*
607*4882a593Smuzhiyun * rsa_get_params(): - Get the important parameters of an RSA public key
608*4882a593Smuzhiyun */
rsa_get_params(RSA * key,uint64_t * exponent,uint32_t * n0_invp,BIGNUM ** modulusp,BIGNUM ** exponent_BN,BIGNUM ** r_squaredp,BIGNUM ** c_factorp,BIGNUM ** np_factorp)609*4882a593Smuzhiyun int rsa_get_params(RSA *key, uint64_t *exponent, uint32_t *n0_invp,
610*4882a593Smuzhiyun BIGNUM **modulusp, BIGNUM **exponent_BN, BIGNUM **r_squaredp,
611*4882a593Smuzhiyun BIGNUM **c_factorp, BIGNUM **np_factorp)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun BIGNUM *big1, *big2, *big32, *big2_32, *big4100, *big2180, *big4228;
614*4882a593Smuzhiyun BIGNUM *n, *e, *r, *r_squared, *tmp, *c_factor, *np_factor;
615*4882a593Smuzhiyun const BIGNUM *key_n, *key_e;
616*4882a593Smuzhiyun BN_CTX *bn_ctx = BN_CTX_new();
617*4882a593Smuzhiyun int ret = 0;
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun /* Initialize BIGNUMs */
620*4882a593Smuzhiyun big1 = BN_new();
621*4882a593Smuzhiyun big2 = BN_new();
622*4882a593Smuzhiyun big32 = BN_new();
623*4882a593Smuzhiyun big4100 = BN_new();
624*4882a593Smuzhiyun big2180 = BN_new();
625*4882a593Smuzhiyun big4228 = BN_new();
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun r = BN_new();
628*4882a593Smuzhiyun r_squared = BN_new();
629*4882a593Smuzhiyun c_factor = BN_new();
630*4882a593Smuzhiyun np_factor = BN_new();
631*4882a593Smuzhiyun tmp = BN_new();
632*4882a593Smuzhiyun big2_32 = BN_new();
633*4882a593Smuzhiyun n = BN_new();
634*4882a593Smuzhiyun e = BN_new();
635*4882a593Smuzhiyun if (!big1 || !big2 || !big32 || !big4100 || !big2180 || !big4228 || !r ||
636*4882a593Smuzhiyun !r_squared || !tmp || !big2_32 || !n || !e ||
637*4882a593Smuzhiyun !c_factor || !np_factor) {
638*4882a593Smuzhiyun fprintf(stderr, "Out of memory (bignum)\n");
639*4882a593Smuzhiyun return -ENOMEM;
640*4882a593Smuzhiyun }
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun if (0 != rsa_get_exponent(key, exponent))
643*4882a593Smuzhiyun ret = -1;
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun RSA_get0_key(key, &key_n, &key_e, NULL);
646*4882a593Smuzhiyun if (!BN_copy(n, key_n) || !BN_copy(e, key_e) ||
647*4882a593Smuzhiyun !BN_set_word(big1, 1L) ||
648*4882a593Smuzhiyun !BN_set_word(big2, 2L) || !BN_set_word(big32, 32L) ||
649*4882a593Smuzhiyun !BN_set_word(big4100, 4100L) || !BN_set_word(big2180, 2180L) ||
650*4882a593Smuzhiyun !BN_set_word(big4228, 4228L))
651*4882a593Smuzhiyun ret = -1;
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun /* big2_32 = 2^32 */
654*4882a593Smuzhiyun if (!BN_exp(big2_32, big2, big32, bn_ctx))
655*4882a593Smuzhiyun ret = -1;
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun /* Calculate n0_inv = -1 / n[0] mod 2^32 */
658*4882a593Smuzhiyun if (!BN_mod_inverse(tmp, n, big2_32, bn_ctx) ||
659*4882a593Smuzhiyun !BN_sub(tmp, big2_32, tmp))
660*4882a593Smuzhiyun ret = -1;
661*4882a593Smuzhiyun *n0_invp = BN_get_word(tmp);
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun /* Calculate R = 2^(# of key bits) */
664*4882a593Smuzhiyun if (!BN_set_word(tmp, BN_num_bits(n)) ||
665*4882a593Smuzhiyun !BN_exp(r, big2, tmp, bn_ctx))
666*4882a593Smuzhiyun ret = -1;
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun /* Calculate r_squared = R^2 mod n */
669*4882a593Smuzhiyun if (!BN_copy(r_squared, r) ||
670*4882a593Smuzhiyun !BN_mul(tmp, r_squared, r, bn_ctx) ||
671*4882a593Smuzhiyun !BN_mod(r_squared, tmp, n, bn_ctx))
672*4882a593Smuzhiyun ret = -1;
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun /* Calculate c_factor = 2^4100 mod n */
675*4882a593Smuzhiyun if (!BN_exp(tmp, big2, big4100, bn_ctx) ||
676*4882a593Smuzhiyun !BN_mod(c_factor, tmp, n, bn_ctx))
677*4882a593Smuzhiyun ret = -1;
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /* Calculate np_factor = 2^2180 div n */
680*4882a593Smuzhiyun if (BN_num_bits(n) == 2048) {
681*4882a593Smuzhiyun if (!BN_exp(tmp, big2, big2180, bn_ctx) ||
682*4882a593Smuzhiyun !BN_div(np_factor, NULL, tmp, n, bn_ctx))
683*4882a593Smuzhiyun ret = -1;
684*4882a593Smuzhiyun } else {/* Calculate 4096 np_factor = 2^4228 div n */
685*4882a593Smuzhiyun if (!BN_exp(tmp, big2, big4228, bn_ctx) ||
686*4882a593Smuzhiyun !BN_div(np_factor, NULL, tmp, n, bn_ctx))
687*4882a593Smuzhiyun ret = -1;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun *modulusp = n;
691*4882a593Smuzhiyun *exponent_BN = e;
692*4882a593Smuzhiyun *r_squaredp = r_squared;
693*4882a593Smuzhiyun *c_factorp = c_factor;
694*4882a593Smuzhiyun *np_factorp = np_factor;
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun BN_free(big1);
697*4882a593Smuzhiyun BN_free(big2);
698*4882a593Smuzhiyun BN_free(big32);
699*4882a593Smuzhiyun BN_free(big4100);
700*4882a593Smuzhiyun BN_free(big2180);
701*4882a593Smuzhiyun BN_free(big4228);
702*4882a593Smuzhiyun BN_free(r);
703*4882a593Smuzhiyun BN_free(tmp);
704*4882a593Smuzhiyun BN_free(big2_32);
705*4882a593Smuzhiyun if (ret) {
706*4882a593Smuzhiyun fprintf(stderr, "Bignum operations failed\n");
707*4882a593Smuzhiyun return -ENOMEM;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun return ret;
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun
rsa_convert_big_endian(uint32_t * dst,const uint32_t * src,int total_len,int convert_len)713*4882a593Smuzhiyun static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src,
714*4882a593Smuzhiyun int total_len, int convert_len)
715*4882a593Smuzhiyun {
716*4882a593Smuzhiyun int total_wd, convert_wd, i;
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun if (total_len < convert_len)
719*4882a593Smuzhiyun convert_len = total_len;
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun total_wd = total_len / sizeof(uint32_t);
722*4882a593Smuzhiyun convert_wd = convert_len / sizeof(uint32_t);
723*4882a593Smuzhiyun for (i = 0; i < convert_wd; i++)
724*4882a593Smuzhiyun dst[i] = fdt32_to_cpu(src[total_wd - 1 - i]);
725*4882a593Smuzhiyun }
726*4882a593Smuzhiyun
rsa_set_key_hash(void * keydest,int key_node,int key_len,const char * csum_algo)727*4882a593Smuzhiyun static int rsa_set_key_hash(void *keydest, int key_node,
728*4882a593Smuzhiyun int key_len, const char *csum_algo)
729*4882a593Smuzhiyun {
730*4882a593Smuzhiyun const void *rsa_n, *rsa_e, *rsa_c, *rsa_np;
731*4882a593Smuzhiyun void *n, *e, *c, *np;
732*4882a593Smuzhiyun uint8_t value[FIT_MAX_HASH_LEN];
733*4882a593Smuzhiyun char hash_c[] = "hash@c";
734*4882a593Smuzhiyun char hash_np[] = "hash@np";
735*4882a593Smuzhiyun char *rsa_key;
736*4882a593Smuzhiyun int hash_node;
737*4882a593Smuzhiyun int value_len;
738*4882a593Smuzhiyun int ret = -ENOSPC;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun rsa_key = calloc(key_len * 3, sizeof(char));
741*4882a593Smuzhiyun if (!rsa_key)
742*4882a593Smuzhiyun return -ENOSPC;
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun rsa_n = fdt_getprop(keydest, key_node, "rsa,modulus", NULL);
745*4882a593Smuzhiyun rsa_e = fdt_getprop(keydest, key_node, "rsa,exponent-BN", NULL);
746*4882a593Smuzhiyun rsa_c = fdt_getprop(keydest, key_node, "rsa,c", NULL);
747*4882a593Smuzhiyun rsa_np = fdt_getprop(keydest, key_node, "rsa,np", NULL);
748*4882a593Smuzhiyun if (!rsa_c || !rsa_np || !rsa_n || !rsa_e)
749*4882a593Smuzhiyun goto err_nospc;
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun n = rsa_key;
752*4882a593Smuzhiyun e = rsa_key + CONFIG_RSA_N_SIZE;
753*4882a593Smuzhiyun rsa_convert_big_endian(n, rsa_n, key_len, CONFIG_RSA_N_SIZE);
754*4882a593Smuzhiyun rsa_convert_big_endian(e, rsa_e, key_len, CONFIG_RSA_E_SIZE);
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun /* hash@c node: n, e, c */
757*4882a593Smuzhiyun c = rsa_key + CONFIG_RSA_N_SIZE + CONFIG_RSA_E_SIZE;
758*4882a593Smuzhiyun rsa_convert_big_endian(c, rsa_c, key_len, CONFIG_RSA_C_SIZE);
759*4882a593Smuzhiyun hash_node = fdt_add_subnode(keydest, key_node, hash_c);
760*4882a593Smuzhiyun if (hash_node < 0)
761*4882a593Smuzhiyun goto err_nospc;
762*4882a593Smuzhiyun ret = calculate_hash(rsa_key, key_len * 3, csum_algo, value, &value_len);
763*4882a593Smuzhiyun if (ret)
764*4882a593Smuzhiyun goto err_nospc;
765*4882a593Smuzhiyun ret = fdt_setprop(keydest, hash_node, FIT_VALUE_PROP, value, value_len);
766*4882a593Smuzhiyun if (ret)
767*4882a593Smuzhiyun goto err_nospc;
768*4882a593Smuzhiyun ret = fdt_setprop_string(keydest, hash_node, FIT_ALGO_PROP, csum_algo);
769*4882a593Smuzhiyun if (ret < 0)
770*4882a593Smuzhiyun goto err_nospc;
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun /* hash@np node: n, e, np */
773*4882a593Smuzhiyun np = rsa_key + CONFIG_RSA_N_SIZE + CONFIG_RSA_E_SIZE;
774*4882a593Smuzhiyun rsa_convert_big_endian(np, rsa_np, key_len, CONFIG_RSA_C_SIZE);
775*4882a593Smuzhiyun hash_node = fdt_add_subnode(keydest, key_node, hash_np);
776*4882a593Smuzhiyun if (hash_node < 0)
777*4882a593Smuzhiyun goto err_nospc;
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun ret = calculate_hash(rsa_key, CONFIG_RSA_N_SIZE + CONFIG_RSA_E_SIZE + CONFIG_RSA_C_SIZE,
780*4882a593Smuzhiyun csum_algo, value, &value_len);
781*4882a593Smuzhiyun if (ret)
782*4882a593Smuzhiyun goto err_nospc;
783*4882a593Smuzhiyun ret = fdt_setprop(keydest, hash_node, FIT_VALUE_PROP, value, value_len);
784*4882a593Smuzhiyun if (ret < 0)
785*4882a593Smuzhiyun goto err_nospc;
786*4882a593Smuzhiyun ret = fdt_setprop_string(keydest, hash_node, FIT_ALGO_PROP, csum_algo);
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun err_nospc:
789*4882a593Smuzhiyun if (rsa_key)
790*4882a593Smuzhiyun free(rsa_key);
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun return ret ? -ENOSPC : 0;
793*4882a593Smuzhiyun }
794*4882a593Smuzhiyun
fdt_add_bignum(void * blob,int noffset,const char * prop_name,BIGNUM * num,int num_bits)795*4882a593Smuzhiyun static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
796*4882a593Smuzhiyun BIGNUM *num, int num_bits)
797*4882a593Smuzhiyun {
798*4882a593Smuzhiyun int nwords = num_bits / 32;
799*4882a593Smuzhiyun int size;
800*4882a593Smuzhiyun uint32_t *buf, *ptr;
801*4882a593Smuzhiyun BIGNUM *tmp, *big2, *big32, *big2_32;
802*4882a593Smuzhiyun BN_CTX *ctx;
803*4882a593Smuzhiyun int ret;
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun tmp = BN_new();
806*4882a593Smuzhiyun big2 = BN_new();
807*4882a593Smuzhiyun big32 = BN_new();
808*4882a593Smuzhiyun big2_32 = BN_new();
809*4882a593Smuzhiyun if (!tmp || !big2 || !big32 || !big2_32) {
810*4882a593Smuzhiyun fprintf(stderr, "Out of memory (bignum)\n");
811*4882a593Smuzhiyun return -ENOMEM;
812*4882a593Smuzhiyun }
813*4882a593Smuzhiyun ctx = BN_CTX_new();
814*4882a593Smuzhiyun if (!tmp) {
815*4882a593Smuzhiyun fprintf(stderr, "Out of memory (bignum context)\n");
816*4882a593Smuzhiyun return -ENOMEM;
817*4882a593Smuzhiyun }
818*4882a593Smuzhiyun BN_set_word(big2, 2L);
819*4882a593Smuzhiyun BN_set_word(big32, 32L);
820*4882a593Smuzhiyun BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun size = nwords * sizeof(uint32_t);
823*4882a593Smuzhiyun buf = malloc(size);
824*4882a593Smuzhiyun if (!buf) {
825*4882a593Smuzhiyun fprintf(stderr, "Out of memory (%d bytes)\n", size);
826*4882a593Smuzhiyun return -ENOMEM;
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun
829*4882a593Smuzhiyun /* Write out modulus as big endian array of integers */
830*4882a593Smuzhiyun for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
831*4882a593Smuzhiyun BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
832*4882a593Smuzhiyun *ptr = cpu_to_fdt32(BN_get_word(tmp));
833*4882a593Smuzhiyun BN_rshift(num, num, 32); /* N = N/B */
834*4882a593Smuzhiyun }
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun /*
837*4882a593Smuzhiyun * We try signing with successively increasing size values, so this
838*4882a593Smuzhiyun * might fail several times
839*4882a593Smuzhiyun */
840*4882a593Smuzhiyun ret = fdt_setprop(blob, noffset, prop_name, buf, size);
841*4882a593Smuzhiyun if (ret)
842*4882a593Smuzhiyun return -FDT_ERR_NOSPACE;
843*4882a593Smuzhiyun free(buf);
844*4882a593Smuzhiyun BN_free(tmp);
845*4882a593Smuzhiyun BN_free(big2);
846*4882a593Smuzhiyun BN_free(big32);
847*4882a593Smuzhiyun BN_free(big2_32);
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun return ret;
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun
rsa_add_verify_data(struct image_sign_info * info,void * keydest)852*4882a593Smuzhiyun int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
853*4882a593Smuzhiyun {
854*4882a593Smuzhiyun BIGNUM *modulus, *exponent_BN, *r_squared, *c_factor, *np_factor;
855*4882a593Smuzhiyun uint64_t exponent;
856*4882a593Smuzhiyun uint32_t n0_inv;
857*4882a593Smuzhiyun int parent, node;
858*4882a593Smuzhiyun char name[100];
859*4882a593Smuzhiyun int ret;
860*4882a593Smuzhiyun int bits;
861*4882a593Smuzhiyun RSA *rsa;
862*4882a593Smuzhiyun ENGINE *e = NULL;
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun debug("%s: Getting verification data\n", __func__);
865*4882a593Smuzhiyun if (info->engine_id) {
866*4882a593Smuzhiyun ret = rsa_engine_init(info->engine_id, &e);
867*4882a593Smuzhiyun if (ret)
868*4882a593Smuzhiyun return ret;
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun ret = rsa_get_pub_key(info->keydir, info->keyname, e, &rsa);
871*4882a593Smuzhiyun if (ret)
872*4882a593Smuzhiyun goto err_get_pub_key;
873*4882a593Smuzhiyun ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus,
874*4882a593Smuzhiyun &exponent_BN, &r_squared, &c_factor, &np_factor);
875*4882a593Smuzhiyun if (ret)
876*4882a593Smuzhiyun goto err_get_params;
877*4882a593Smuzhiyun bits = BN_num_bits(modulus);
878*4882a593Smuzhiyun parent = fdt_subnode_offset(keydest, 0, FIT_SIG_NODENAME);
879*4882a593Smuzhiyun if (parent == -FDT_ERR_NOTFOUND) {
880*4882a593Smuzhiyun parent = fdt_add_subnode(keydest, 0, FIT_SIG_NODENAME);
881*4882a593Smuzhiyun if (parent < 0) {
882*4882a593Smuzhiyun ret = parent;
883*4882a593Smuzhiyun if (ret != -FDT_ERR_NOSPACE) {
884*4882a593Smuzhiyun fprintf(stderr, "Couldn't create signature node: %s\n",
885*4882a593Smuzhiyun fdt_strerror(parent));
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun }
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun if (ret)
890*4882a593Smuzhiyun goto done;
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun /* Either create or overwrite the named key node */
893*4882a593Smuzhiyun snprintf(name, sizeof(name), "key-%s", info->keyname);
894*4882a593Smuzhiyun node = fdt_subnode_offset(keydest, parent, name);
895*4882a593Smuzhiyun if (node == -FDT_ERR_NOTFOUND) {
896*4882a593Smuzhiyun node = fdt_add_subnode(keydest, parent, name);
897*4882a593Smuzhiyun if (node < 0) {
898*4882a593Smuzhiyun ret = node;
899*4882a593Smuzhiyun if (ret != -FDT_ERR_NOSPACE) {
900*4882a593Smuzhiyun fprintf(stderr, "Could not create key subnode: %s\n",
901*4882a593Smuzhiyun fdt_strerror(node));
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun }
904*4882a593Smuzhiyun } else if (node < 0) {
905*4882a593Smuzhiyun fprintf(stderr, "Cannot select keys parent: %s\n",
906*4882a593Smuzhiyun fdt_strerror(node));
907*4882a593Smuzhiyun ret = node;
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun if (!ret) {
911*4882a593Smuzhiyun ret = fdt_setprop_string(keydest, node, "key-name-hint",
912*4882a593Smuzhiyun info->keyname);
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun if (!ret)
915*4882a593Smuzhiyun ret = fdt_setprop_u32(keydest, node, "rsa,num-bits", bits);
916*4882a593Smuzhiyun if (!ret)
917*4882a593Smuzhiyun ret = fdt_setprop_u32(keydest, node, "rsa,n0-inverse", n0_inv);
918*4882a593Smuzhiyun if (!ret) {
919*4882a593Smuzhiyun ret = fdt_setprop_u64(keydest, node, "rsa,exponent", exponent);
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun if (!ret) {
922*4882a593Smuzhiyun ret = fdt_add_bignum(keydest, node, "rsa,exponent-BN",
923*4882a593Smuzhiyun exponent_BN, bits);
924*4882a593Smuzhiyun }
925*4882a593Smuzhiyun if (!ret) {
926*4882a593Smuzhiyun ret = fdt_add_bignum(keydest, node, "rsa,modulus", modulus,
927*4882a593Smuzhiyun bits);
928*4882a593Smuzhiyun }
929*4882a593Smuzhiyun if (!ret) {
930*4882a593Smuzhiyun ret = fdt_add_bignum(keydest, node, "rsa,r-squared", r_squared,
931*4882a593Smuzhiyun bits);
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun if (!ret) {
934*4882a593Smuzhiyun ret = fdt_add_bignum(keydest, node, "rsa,c", c_factor,
935*4882a593Smuzhiyun bits);
936*4882a593Smuzhiyun }
937*4882a593Smuzhiyun if (!ret) {
938*4882a593Smuzhiyun ret = fdt_add_bignum(keydest, node, "rsa,np", np_factor,
939*4882a593Smuzhiyun bits);
940*4882a593Smuzhiyun }
941*4882a593Smuzhiyun if (!ret) {
942*4882a593Smuzhiyun ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP,
943*4882a593Smuzhiyun info->name);
944*4882a593Smuzhiyun }
945*4882a593Smuzhiyun if (!ret && info->require_keys) {
946*4882a593Smuzhiyun ret = fdt_setprop_string(keydest, node, "required",
947*4882a593Smuzhiyun info->require_keys);
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun if (!ret) {
950*4882a593Smuzhiyun ret = rsa_set_key_hash(keydest, node, info->crypto->key_len,
951*4882a593Smuzhiyun info->checksum->name);
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun done:
954*4882a593Smuzhiyun BN_free(modulus);
955*4882a593Smuzhiyun BN_free(r_squared);
956*4882a593Smuzhiyun if (ret)
957*4882a593Smuzhiyun ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
958*4882a593Smuzhiyun err_get_params:
959*4882a593Smuzhiyun RSA_free(rsa);
960*4882a593Smuzhiyun err_get_pub_key:
961*4882a593Smuzhiyun if (info->engine_id)
962*4882a593Smuzhiyun rsa_engine_remove(e);
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun return ret;
965*4882a593Smuzhiyun }
966