Add ECDSA support for FIT image verification
Subsystems (6)
v4 cover Add ECDSA support for FIT image verification
This series implements ECDSA signature verification for FIT images. The ECDSA code itself is taken from the Kernel. Currently only supported way to specify a ECDSA key is to compile it into the binary using CONFIG_CRYPTO_PUBLIC_KEYS, taking it from a device tree is not yet supported.
Since v2 this series unifies the way public keys are passed to barebox. We now have a single Kconfig option which takes a list of public keys, which can be either RSA or ECDSA keys.
Changes since v3:
- add patch to remove unnecessary dependencies from public-keys.h
- add commit message to "crypto: Makefile: make simpler"
Changes since v2:
- fix endianess problems when ECDSA keys are built for a machine with different endianess
- add struct public_key as a container for different key types
- make FIT image code use generic public key functions
- drop ECDSA dts snippet support (not needed, doesn't work)
- pass NULL to EVP_PKEY_get_utf8_string_param()
Sascha Hauer (16):
keytoc: remove ECDSA dts support
keytoc: fail in case gen_key() fails
keytoc: fix ECDSA endianess problems
keytoc: remove duplicate __ENV__ check
crypto: Makefile: make simpler
crypto/Makefile: Drop unnecessary dependencies
keytoc: make key name hint optional
crypto: rsa: include key name hint into CONFIG_CRYPTO_RSA_KEY
crypto: rsa: encapsulate rsa keys in public keys struct
crypto: add public_key functions
crypto: builtin_keys: Allow to specify multiple keys in
CONFIG_CRYPTO_PUBLIC_KEYS
crypto: public-keys: use array of public_keys
crypto: rsa: create static inline wrapper for rsa_verify() Add elliptic curve cryptography (ECC) helper functions
crypto: add ECDSA support
crypto: make RSA a visible option
common/Kconfig | 1 - common/image-fit.c | 20 +- crypto/Kconfig | 37 +- crypto/Makefile | 18 +- crypto/ecc.c | 1661 +++++++++++++++++++++++++++++ crypto/ecc_curve_defs.h | 155 +++ crypto/ecdsa.c | 140 +++ crypto/public-keys.c | 107 ++ crypto/rsa.c | 95 +- include/asm-generic/barebox.lds.h | 10 +- include/crypto/ecc_curve.h | 62 ++ include/crypto/ecdh.h | 83 ++ include/crypto/internal/ecc.h | 278 +++++ include/crypto/public_key.h | 36 + include/ecdsa.h | 42 + include/rsa.h | 35 +- scripts/Makefile.lib | 2 +- scripts/keytoc.c | 119 ++- 18 files changed, 2716 insertions(+), 185 deletions(-) create mode 100644 crypto/ecc.c create mode 100644 crypto/ecc_curve_defs.h create mode 100644 crypto/ecdsa.c create mode 100644 crypto/public-keys.c create mode 100644 include/crypto/ecc_curve.h create mode 100644 include/crypto/ecdh.h create mode 100644 include/crypto/internal/ecc.h create mode 100644 include/crypto/public_key.h create mode 100644 include/ecdsa.h
Signature · 1 line
2.39.2
PATCH v4 1/16 keytoc: remove ECDSA dts support
Generating dts snippets for ECDSA keys does not work properly, there are various endianess problems. As we do not need this currently for barebox drop the support for now.
--- scripts/keytoc.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
scripts/keytoc.c +5 -9
@@ -470,15 +470,8 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_nareturn -EINVAL ;if (dts) { -fprintf (outfilep,"\t\tkey-%s {\n" , key_name_c); -fprintf (outfilep,"\t\t\tecdsa,x-point = <" ); -print_bignum (key_x, bits); -fprintf (outfilep,">;\n" ); -fprintf (outfilep,"\t\t\tecdsa,y-point = <" ); -print_bignum (key_y, bits); -fprintf (outfilep,">;\n" ); -fprintf (outfilep,"\t\t\tecdsa,curve = \"%s\";\n" , group); -fprintf (outfilep,"\t\t};\n" ); +fprintf (stderr,"ERROR: generating a dts snippet for ECDSA keys is not yet supported\n" ); +return -EOPNOTSUPP ; }else {fprintf (outfilep,"\nstatic uint32_t %s_x[] = {" , key_name_c);print_bignum (key_x, bits);
@@ -598,6 +591,9 @@ static int gen_key(const char *keyname, const char *path) } ret =gen_key_ecdsa (key, keyname, key_name_c); +if (ret == -EOPNOTSUPP ) +return ret; +if (ret) ret =gen_key_rsa (key, keyname, key_name_c);
Signature · 1 line
2.39.2
Re: [PATCH v4 01/16] keytoc: remove ECDSA dts support
Quoted 5 lines · Sascha Hauer
Generating dts snippets for ECDSA keys does not work properly, there are various endianess problems. As we do not need this currently for barebox drop the support for now.
Signed-off-by Sascha Hauer <[email protected]>
Quoted 36 lines
--- scripts/keytoc.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)scripts/keytoc.c +5
-9@@ -470,15 +470,8 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_nareturn -EINVAL ;if (dts) { -fprintf (outfilep,"\t\tkey-%s {\n" , key_name_c); -fprintf (outfilep,"\t\t\tecdsa,x-point = <" ); -print_bignum (key_x, bits); -fprintf (outfilep,">;\n" ); -fprintf (outfilep,"\t\t\tecdsa,y-point = <" ); -print_bignum (key_y, bits); -fprintf (outfilep,">;\n" ); -fprintf (outfilep,"\t\t\tecdsa,curve = \"%s\";\n" , group); -fprintf (outfilep,"\t\t};\n" ); +fprintf (stderr,"ERROR: generating a dts snippet for ECDSA keys is not yet supported\n" ); +return -EOPNOTSUPP ; }else {fprintf (outfilep,"\nstatic uint32_t %s_x[] = {" , key_name_c);print_bignum (key_x, bits);@@ -598,6 +591,9 @@ static int gen_key(const char *keyname, const char *path) } ret =gen_key_ecdsa (key, keyname, key_name_c); +if (ret == -EOPNOTSUPP ) +return ret; +if (ret) ret =gen_key_rsa (key, keyname, key_name_c);
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 2/16 keytoc: fail in case gen_key() fails
In reply to Sascha HauerIn case of an error in gen_key() return an error code so that the keytoc tool returns an error.
--- scripts/keytoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/keytoc.c +1 -1
@@ -597,7 +597,7 @@ static int gen_key(const char *keyname, const char *path)if (ret) ret =gen_key_rsa (key, keyname, key_name_c); -return 0 ; +return ret; }int main (int argc,char *argv[])
Signature · 1 line
2.39.2
Re: [PATCH v4 02/16] keytoc: fail in case gen_key() fails
Quoted 4 lines · Sascha Hauer
In case of an error in
gen_key()return an error code so that the keytoc tool returns an error.Signed-off-by Sascha Hauer <[email protected]>
Quoted 17 lines
--- scripts/keytoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)scripts/keytoc.c +1
-1@@ -597,7 +597,7 @@ static int gen_key(const char *keyname, const char *path)if (ret) ret =gen_key_rsa (key, keyname, key_name_c); -return 0 ; +return ret; }int main (int argc,char *argv[])
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 3/16 keytoc: fix ECDSA endianess problems
In reply to Sascha HauerWe print the ECDSA key values out as an uint32_t C array. They are used in barebox as a uint64_t C array, so when the endianess of the build system differs from the system barebox runs on we end up with the 32bit words swapped in the u64 array. Fix this by printing out the key values as an uint64_t array.
--- scripts/keytoc.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-)
scripts/keytoc.c +21 -21
@@ -315,12 +315,12 @@ static int rsa_get_params(EVP_PKEY *key, uint64_t *exponent, uint32_t *n0_invp,static FILE *outfilep; -static int print_bignum (BIGNUM *num,int num_bits) +static int print_bignum (BIGNUM *num,int num_bits,int width) {BIGNUM *tmp, *big2, *big32, *big2_32;BN_CTX *ctx;int i; -uint32_t *arr; +uint64_t *arr; tmp =BN_new (); big2 =BN_new ();
@@ -345,34 +345,34 @@ static int print_bignum(BIGNUM *num, int num_bits)return -ENOMEM ; }BN_set_word (big2,2L ); -BN_set_word (big32,32L ); -BN_exp (big2_32, big2, big32, ctx);/* B = 2^32 */ +BN_set_word (big32, width); +BN_exp (big2_32, big2, big32, ctx);/* B = 2^width */ - arr =malloc (num_bits /32 *sizeof (uint32_t )); + arr =malloc (num_bits / width *sizeof (*arr)); -for (i =0 ; i < num_bits /32 ; i++) { +for (i =0 ; i < num_bits / width; i++) {BN_mod (tmp, num, big2_32, ctx);/* n = N mod B */ arr[i] =BN_get_word (tmp); -BN_rshift (num, num,32 );/* N = N/B */ +BN_rshift (num, num, width);/* N = N/B */ }if (dts) { -for (i =0 ; i < num_bits /32 ; i++) { +for (i =0 ; i < num_bits / width; i++) {if (i %4 )fprintf (outfilep," " );else fprintf (outfilep,"\n\t\t\t\t" ); -fprintf (outfilep,"0x%08x" , arr[num_bits /32 -1 - i]); -BN_rshift (num, num,32 );/* N = N/B */ +fprintf (outfilep,"0x%0*jx" , width /4 , arr[num_bits / width -1 - i]); +BN_rshift (num, num, width);/* N = N/B */ } }else { -for (i =0 ; i < num_bits /32 ; i++) { +for (i =0 ; i < num_bits / width; i++) {if (i %4 )fprintf (outfilep," " );else fprintf (outfilep,"\n\t" ); -fprintf (outfilep,"0x%08x," , arr[i]); -BN_rshift (num, num,32 );/* N = N/B */ +fprintf (outfilep,"0x%0*jx," , width /4 , arr[i]); +BN_rshift (num, num, width);/* N = N/B */ } }
@@ -473,12 +473,12 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_nafprintf (stderr,"ERROR: generating a dts snippet for ECDSA keys is not yet supported\n" );return -EOPNOTSUPP ; }else { -fprintf (outfilep,"\nstatic uint32_t %s_x[] = {" , key_name_c); -print_bignum (key_x, bits); +fprintf (outfilep,"\nstatic uint64_t %s_x[] = {" , key_name_c); +print_bignum (key_x, bits,64 );fprintf (outfilep,"\n};\n\n" ); -fprintf (outfilep,"static uint32_t %s_y[] = {" , key_name_c); -print_bignum (key_y, bits); +fprintf (outfilep,"static uint64_t %s_y[] = {" , key_name_c); +print_bignum (key_y, bits,64 );fprintf (outfilep,"\n};\n\n" );fprintf (outfilep,"static struct ecdsa_public_key %s = {\n" , key_name_c);
@@ -512,10 +512,10 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_nameif (dts) {fprintf (outfilep,"\t\tkey-%s {\n" , key_name_c);fprintf (outfilep,"\t\t\trsa,r-squared = <" ); -print_bignum (r_squared, bits); +print_bignum (r_squared, bits,32 );fprintf (outfilep,">;\n" );fprintf (outfilep,"\t\t\trsa,modulus= <" ); -print_bignum (modulus, bits); +print_bignum (modulus, bits,32 );fprintf (outfilep,">;\n" ); fprintf(outfilep, "\t\t\trsa,exponent = <0x%0lx 0x%lx>;\n", (exponent >> 32) & 0xffffffff,
@@ -526,11 +526,11 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_namefprintf (outfilep,"\t\t};\n" ); }else {fprintf (outfilep,"\nstatic uint32_t %s_modulus[] = {" , key_name_c); -print_bignum (modulus, bits); +print_bignum (modulus, bits,32 );fprintf (outfilep,"\n};\n\n" );fprintf (outfilep,"static uint32_t %s_rr[] = {" , key_name_c); -print_bignum (r_squared, bits); +print_bignum (r_squared, bits,32 );fprintf (outfilep,"\n};\n\n" );if (standalone) {
Signature · 1 line
2.39.2
Re: [PATCH v4 03/16] keytoc: fix ECDSA endianess problems
Quoted 7 lines · Sascha Hauer
We print the ECDSA key values out as an
uint32_tC array. They are used in barebox as auint64_tC array, so when the endianess of the build system differs from the system barebox runs on we end up with the 32bit words swapped in the u64 array. Fix this by printing out the key values as anuint64_tarray.Signed-off-by Sascha Hauer <[email protected]>
Cool, thanks. Now we just need a tes and see it work on big-endian MIPS :-)
Cheers,
Ahmad
Quoted 113 lines
--- scripts/keytoc.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-)scripts/keytoc.c +21
-21@@ -315,12 +315,12 @@ static int rsa_get_params(EVP_PKEY *key, uint64_t *exponent, uint32_t *n0_invp,static FILE *outfilep; -static int print_bignum (BIGNUM *num,int num_bits) +static int print_bignum (BIGNUM *num,int num_bits,int width) {BIGNUM *tmp, *big2, *big32, *big2_32;BN_CTX *ctx;int i; -uint32_t *arr; +uint64_t *arr; tmp =BN_new (); big2 =BN_new ();@@ -345,34 +345,34 @@ static int print_bignum(BIGNUM *num, int num_bits)return -ENOMEM ; }BN_set_word (big2,2L ); -BN_set_word (big32,32L ); -BN_exp (big2_32, big2, big32, ctx);/* B = 2^32 */ +BN_set_word (big32, width); +BN_exp (big2_32, big2, big32, ctx);/* B = 2^width */ - arr =malloc (num_bits /32 *sizeof (uint32_t )); + arr =malloc (num_bits / width *sizeof (*arr)); -for (i =0 ; i < num_bits /32 ; i++) { +for (i =0 ; i < num_bits / width; i++) {BN_mod (tmp, num, big2_32, ctx);/* n = N mod B */ arr[i] =BN_get_word (tmp); -BN_rshift (num, num,32 );/* N = N/B */ +BN_rshift (num, num, width);/* N = N/B */ }if (dts) { -for (i =0 ; i < num_bits /32 ; i++) { +for (i =0 ; i < num_bits / width; i++) {if (i %4 )fprintf (outfilep," " );else fprintf (outfilep,"\n\t\t\t\t" ); -fprintf (outfilep,"0x%08x" , arr[num_bits /32 -1 - i]); -BN_rshift (num, num,32 );/* N = N/B */ +fprintf (outfilep,"0x%0*jx" , width /4 , arr[num_bits / width -1 - i]); +BN_rshift (num, num, width);/* N = N/B */ } }else { -for (i =0 ; i < num_bits /32 ; i++) { +for (i =0 ; i < num_bits / width; i++) {if (i %4 )fprintf (outfilep," " );else fprintf (outfilep,"\n\t" ); -fprintf (outfilep,"0x%08x," , arr[i]); -BN_rshift (num, num,32 );/* N = N/B */ +fprintf (outfilep,"0x%0*jx," , width /4 , arr[i]); +BN_rshift (num, num, width);/* N = N/B */ } }@@ -473,12 +473,12 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_nafprintf (stderr,"ERROR: generating a dts snippet for ECDSA keys is not yet supported\n" );return -EOPNOTSUPP ; }else { -fprintf (outfilep,"\nstatic uint32_t %s_x[] = {" , key_name_c); -print_bignum (key_x, bits); +fprintf (outfilep,"\nstatic uint64_t %s_x[] = {" , key_name_c); +print_bignum (key_x, bits,64 );fprintf (outfilep,"\n};\n\n" ); -fprintf (outfilep,"static uint32_t %s_y[] = {" , key_name_c); -print_bignum (key_y, bits); +fprintf (outfilep,"static uint64_t %s_y[] = {" , key_name_c); +print_bignum (key_y, bits,64 );fprintf (outfilep,"\n};\n\n" );fprintf (outfilep,"static struct ecdsa_public_key %s = {\n" , key_name_c);@@ -512,10 +512,10 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_nameif (dts) {fprintf (outfilep,"\t\tkey-%s {\n" , key_name_c);fprintf (outfilep,"\t\t\trsa,r-squared = <" ); -print_bignum (r_squared, bits); +print_bignum (r_squared, bits,32 );fprintf (outfilep,">;\n" );fprintf (outfilep,"\t\t\trsa,modulus= <" ); -print_bignum (modulus, bits); +print_bignum (modulus, bits,32 );fprintf (outfilep,">;\n" ); fprintf(outfilep, "\t\t\trsa,exponent = <0x%0lx 0x%lx>;\n", (exponent >> 32) & 0xffffffff,@@ -526,11 +526,11 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_namefprintf (outfilep,"\t\t};\n" ); }else {fprintf (outfilep,"\nstatic uint32_t %s_modulus[] = {" , key_name_c); -print_bignum (modulus, bits); +print_bignum (modulus, bits,32 );fprintf (outfilep,"\n};\n\n" );fprintf (outfilep,"static uint32_t %s_rr[] = {" , key_name_c); -print_bignum (r_squared, bits); +print_bignum (r_squared, bits,32 );fprintf (outfilep,"\n};\n\n" );if (standalone) {
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 4/16 keytoc: remove duplicate __ENV__ check
In reply to Sascha Hauer--- scripts/keytoc.c | 11 ----------- 1 file changed, 11 deletions(-)
scripts/keytoc.c +0 -11
@@ -664,17 +664,6 @@ int main(int argc, char *argv[]) *path =0 ; path++; -if (!strncmp (path,"__ENV__" ,7 )) { -const char *orig_path = path; - - path =getenv (orig_path +7 ); -if (!path) { -fprintf (stderr,"%s doesn't contain a path\n" , - orig_path +7 ); -exit (1 ); - } - } - ret =gen_key (keyname, path);if (ret)exit (1 );
Signature · 1 line
2.39.2
Re: [PATCH v4 04/16] keytoc: remove duplicate __ENV__ check
Quoted 1 line · Sascha Hauer
Signed-off-by Sascha Hauer <[email protected]>
Quoted 26 lines
--- scripts/keytoc.c | 11 ----------- 1 file changed, 11 deletions(-)scripts/keytoc.c +0
-11@@ -664,17 +664,6 @@ int main(int argc, char *argv[]) *path =0 ; path++; -if (!strncmp (path,"__ENV__" ,7 )) { -const char *orig_path = path; - - path =getenv (orig_path +7 ); -if (!path) { -fprintf (stderr,"%s doesn't contain a path\n" , - orig_path +7 ); -exit (1 ); - } - } - ret =gen_key (keyname, path);if (ret)exit (1 );
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 5/16 crypto: Makefile: make simpler
In reply to Sascha HauerWe have:
$(if $(RSA_DEP),$<,$(CONFIG_CRYPTO_RSA_KEY))
'$<' is the first dependency which is $(RSA_DEP). $(RSA_DEP) is either empty (in which case $(CONFIG_CRYPTO_RSA_KEY) is used), or set to $(CONFIG_CRYPTO_RSA_KEY) a few lines up.
so all this is a complicated way of using $(CONFIG_CRYPTO_RSA_KEY) directly.
--- crypto/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
crypto/Makefile +1 -1
@@ -34,5 +34,5 @@ RSA_DEP := $(CONFIG_CRYPTO_RSA_KEY) endif $(obj)/rsa-keys.h: $(RSA_DEP) FORCE - $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(if $(RSA_DEP),$<,$(CONFIG_CRYPTO_RSA_KEY))) + $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(CONFIG_CRYPTO_RSA_KEY)) endif
Signature · 1 line
2.39.2
Re: [PATCH v4 05/16] crypto: Makefile: make simpler
Quoted 11 lines · Sascha Hauer
We have:
$(if $(RSA_DEP),$<,$(CONFIG_CRYPTO_RSA_KEY))
'$<' is the first dependency which is $(RSA_DEP). $(RSA_DEP) is either empty (in which case $(CONFIG_CRYPTO_RSA_KEY) is used), or set to $(CONFIG_CRYPTO_RSA_KEY) a few lines up.
so all this is a complicated way of using $(CONFIG_CRYPTO_RSA_KEY) directly.Signed-off-by Sascha Hauer <[email protected]>
Quoted 15 lines
--- crypto/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)crypto/Makefile +1
-1@@ -34,5 +34,5 @@ RSA_DEP := $(CONFIG_CRYPTO_RSA_KEY) endif $(obj)/rsa-keys.h: $(RSA_DEP) FORCE - $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(if $(RSA_DEP),$<,$(CONFIG_CRYPTO_RSA_KEY))) + $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(CONFIG_CRYPTO_RSA_KEY)) endif
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 6/16 crypto/Makefile: Drop unnecessary dependencies
In reply to Sascha HauerHaving rsa-keys.h depend on the input key files is unnecessary. They were introduced to avoid unnecessary rebuilds when the files didn't change. This is unnecessary because the public_keys cmd won't produce output when it wouldn't change the existing file.
--- crypto/Makefile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
crypto/Makefile +1 -5
@@ -29,10 +29,6 @@ $(obj)/rsa.o: $(obj)/rsa-keys.h CONFIG_CRYPTO_RSA_KEY := $(CONFIG_CRYPTO_RSA_KEY:"%"=%) -ifneq ($(filter-out pkcs11:% __ENV__%, $(CONFIG_CRYPTO_RSA_KEY)),) -RSA_DEP := $(CONFIG_CRYPTO_RSA_KEY) -endif - -$(obj)/rsa-keys.h: $(RSA_DEP) FORCE +$(obj)/rsa-keys.h: FORCE $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(CONFIG_CRYPTO_RSA_KEY)) endif
Signature · 1 line
2.39.2
Re: [PATCH v4 06/16] crypto/Makefile: Drop unnecessary dependencies
Quoted 6 lines · Sascha Hauer
Having
rsa-keys.hdepend on the input key files is unnecessary. They were introduced to avoid unnecessary rebuilds when the files didn't change. This is unnecessary because thepublic_keyscmd won't produce output when it wouldn't change the existing file.Signed-off-by Sascha Hauer <[email protected]>
Quoted 20 lines
--- crypto/Makefile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)crypto/Makefile +1
-5@@ -29,10 +29,6 @@ $(obj)/rsa.o: $(obj)/rsa-keys.h CONFIG_CRYPTO_RSA_KEY := $(CONFIG_CRYPTO_RSA_KEY:"%"=%) -ifneq ($(filter-out pkcs11:% __ENV__%, $(CONFIG_CRYPTO_RSA_KEY)),) -RSA_DEP := $(CONFIG_CRYPTO_RSA_KEY) -endif - -$(obj)/rsa-keys.h: $(RSA_DEP) FORCE +$(obj)/rsa-keys.h: FORCE $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(CONFIG_CRYPTO_RSA_KEY)) endif
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 7/16 keytoc: make key name hint optional
In reply to Sascha HauerThe key name hint is used in barebox to find a key without iterating over all keys, but it's not required. Make the key name hint optional to keytoc.
--- scripts/keytoc.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
scripts/keytoc.c +22 -9
@@ -9,6 +9,7 @@* */ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#define _GNU_SOURCE#include <stdio.h> #include <string.h> #include <time.h>
@@ -602,9 +603,9 @@ static int gen_key(const char *keyname, const char *path)int main (int argc,char *argv[]) { -char *path, *keyname;int i, opt, ret;char *outfile =NULL ; +int keynum =1 ; outfilep = stdout;
@@ -652,21 +653,33 @@ int main(int argc, char *argv[]) }for (i = optind; i < argc; i++) { - keyname = argv[i]; +char *keyspec = argv[i]; +char *keyname =NULL ; +char *path, *freep =NULL ; - path =strchr (keyname,':' ); -if (!path) { -fprintf (stderr, -"keys must be given as <key_name_hint>:<crt>\n" ); -exit (1 ); +if (!strncmp (keyspec,"pkcs11:" ,7 )) { + path = keyspec; + }else { + path =strchr (keyspec,':' ); +if (path) { + *path =0 ; + path++; + keyname = keyspec; + }else { + path = keyspec; + } } - *path =0 ; - path++; +if (!keyname) { +asprintf (&freep,"key_%d" , keynum++); + keyname = freep; + } ret =gen_key (keyname, path);if (ret)exit (1 ); + +free (freep); }if (dts) {
Signature · 1 line
2.39.2
Re: [PATCH v4 07/16] keytoc: make key name hint optional
Quoted 5 lines · Sascha Hauer
The key name hint is used in barebox to find a key without iterating over all keys, but it's not required. Make the key name hint optional to keytoc.
Signed-off-by Sascha Hauer <[email protected]>
Quoted 69 lines
--- scripts/keytoc.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)scripts/keytoc.c +22
-9@@ -9,6 +9,7 @@* */ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#define _GNU_SOURCE#include <stdio.h> #include <string.h> #include <time.h> @@ -602,9 +603,9 @@ static int gen_key(const char *keyname, const char *path)int main (int argc,char *argv[]) { -char *path, *keyname;int i, opt, ret;char *outfile =NULL ; +int keynum =1 ; outfilep = stdout;@@ -652,21 +653,33 @@ int main(int argc, char *argv[]) }for (i = optind; i < argc; i++) { - keyname = argv[i]; +char *keyspec = argv[i]; +char *keyname =NULL ; +char *path, *freep =NULL ; - path =strchr (keyname,':' ); -if (!path) { -fprintf (stderr, -"keys must be given as <key_name_hint>:<crt>\n" ); -exit (1 ); +if (!strncmp (keyspec,"pkcs11:" ,7 )) { + path = keyspec; + }else { + path =strchr (keyspec,':' ); +if (path) { + *path =0 ; + path++; + keyname = keyspec; + }else { + path = keyspec; + } } - *path =0 ; - path++; +if (!keyname) { +asprintf (&freep,"key_%d" , keynum++); + keyname = freep; + } ret =gen_key (keyname, path);if (ret)exit (1 ); + +free (freep); }if (dts) {
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 8/16 crypto: rsa: include key name hint into CONFIG_CRYPTO_RSA_KEY
In reply to Sascha HauerSet the key name hint in CONFIG_CRYPTO_RSA_KEY. CONFIG_CRYPTO_RSA_KEY now has the form:
<key_name_hint>:<filename/uri>
This is done in preparation to make CONFIG_CRYPTO_RSA_KEY a list of keys.
--- crypto/Kconfig | 9 ++------- crypto/Makefile | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-)
crypto/Kconfig +2 -7
@@ -130,17 +130,12 @@ config CRYPTO_RSA_KEY This option should be a filename of a PEM-formatted file containing X.509 certificates to be included into barebox. If the string starts with "pkcs11:" it is interpreted as a PKCS#11 URI rather than a file. + If the string starts with a <hint>: prefix, <hint> is used as a key + name hint to find a key without iterating over all keys. This avoids the mkimage dependency of CONFIG_BOOTM_FITIMAGE_PUBKEY at the cost of an openssl build-time dependency. -config CRYPTO_RSA_KEY_NAME_HINT - depends on CRYPTO_RSA - string "FIT image key name hint" - help - In FIT images keys are identified by a key name hint string. Provide - the key name hint here. - config CRYPTO_KEYSTORE bool "Keystore" help
crypto/Makefile +1 -1
@@ -30,5 +30,5 @@ $(obj)/rsa.o: $(obj)/rsa-keys.h CONFIG_CRYPTO_RSA_KEY := $(CONFIG_CRYPTO_RSA_KEY:"%"=%) $(obj)/rsa-keys.h: FORCE - $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(CONFIG_CRYPTO_RSA_KEY)) + $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY)) endif
Signature · 1 line
2.39.2
Re: [PATCH v4 08/16] crypto: rsa: include key name hint into CONFIG_CRYPTO_RSA_KEY
Quoted 9 lines · Sascha Hauer
Set the key name hint in
CONFIG_CRYPTO_RSA_KEY.CONFIG_CRYPTO_RSA_KEYnow has the form:<key_name_hint>:<filename/uri>
This is done in preparation to make
CONFIG_CRYPTO_RSA_KEYa list of keys.Signed-off-by Sascha Hauer <[email protected]>
Quoted 40 lines
--- crypto/Kconfig | 9 ++------- crypto/Makefile | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-)crypto/Kconfig +2
-7@@ -130,17 +130,12 @@ config CRYPTO_RSA_KEY This option should be a filename of a PEM-formatted file containing X.509 certificates to be included into barebox. If the string starts with "pkcs11:" it is interpreted as a PKCS#11 URI rather than a file. + If the string starts with a <hint>: prefix, <hint> is used as a key + name hint to find a key without iterating over all keys. This avoids the mkimage dependency of CONFIG_BOOTM_FITIMAGE_PUBKEY at the cost of an openssl build-time dependency. -config CRYPTO_RSA_KEY_NAME_HINT - depends on CRYPTO_RSA - string "FIT image key name hint" - help - In FIT images keys are identified by a key name hint string. Provide - the key name hint here. - config CRYPTO_KEYSTORE bool "Keystore" helpcrypto/Makefile +1
-1@@ -30,5 +30,5 @@ $(obj)/rsa.o: $(obj)/rsa-keys.h CONFIG_CRYPTO_RSA_KEY := $(CONFIG_CRYPTO_RSA_KEY:"%"=%) $(obj)/rsa-keys.h: FORCE - $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(CONFIG_CRYPTO_RSA_KEY)) + $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY)) endif
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 9/16 crypto: rsa: encapsulate rsa keys in public keys struct
In reply to Sascha HauerThis encapsulates struct rsa_public_key into a struct public_key. So far RSA keys are the only supported key type. With adding ECDSA keys we need a container struct so that we can add ECDSA keys using the same mechanisms.
Also we rename CONFIG_CRYPTO_RSA_KEY to CONFIG_CRYPTO_PUBLIC_KEYS and CONFIG_CRYPTO_RSA_BUILTIN_KEYS to CONFIG_CRYPTO_BUILTIN_KEYS as these variables will be used for all types of keys, not only RSA keys.
--- crypto/Kconfig | 11 ++++----- crypto/Makefile | 14 ++++++----- crypto/public-keys.c | 39 +++++++++++++++++++++++++++++++ crypto/rsa.c | 23 ++---------------- include/asm-generic/barebox.lds.h | 10 ++++---- include/crypto/public_key.h | 20 ++++++++++++++++ include/rsa.h | 16 +++++++++++++ scripts/keytoc.c | 18 ++++++++++---- 8 files changed, 109 insertions(+), 42 deletions(-) create mode 100644 crypto/public-keys.c create mode 100644 include/crypto/public_key.h
crypto/Kconfig +5 -6
@@ -118,14 +118,13 @@ config CRYPTO_PBKDF2 config CRYPTO_RSA bool -config CRYPTO_RSA_BUILTIN_KEYS - bool - default y if CRYPTO_RSA_KEY != "" +config CRYPTO_BUILTIN_KEYS + bool "builtin keys" select KEYTOC -config CRYPTO_RSA_KEY - depends on CRYPTO_RSA - string "RSA key to compile in" +config CRYPTO_PUBLIC_KEYS + depends on CRYPTO_BUILTIN_KEYS + string "public keys to compile in" help This option should be a filename of a PEM-formatted file containing X.509 certificates to be included into barebox. If the string starts
crypto/Makefile +8 -6
@@ -18,17 +18,19 @@ obj-y += memneq.o obj-$(CONFIG_CRYPTO_PBKDF2) += pbkdf2.o obj-$(CONFIG_CRYPTO_RSA) += rsa.o obj-$(CONFIG_CRYPTO_KEYSTORE) += keystore.o +obj-$(CONFIG_CRYPTO_BUILTIN_KEYS) += public-keys.o obj-$(CONFIG_JWT) += jwt.o -extra-$(CONFIG_CRYPTO_RSA_BUILTIN_KEYS) += rsa-keys.h +extra-$(CONFIG_CRYPTO_BUILTIN_KEYS) += public-keys.h -ifdef CONFIG_CRYPTO_RSA_BUILTIN_KEYS +ifdef CONFIG_CRYPTO_BUILTIN_KEYS -$(obj)/rsa.o: $(obj)/rsa-keys.h +$(obj)/public-keys.o: $(obj)/public-keys.h -CONFIG_CRYPTO_RSA_KEY := $(CONFIG_CRYPTO_RSA_KEY:"%"=%) +CONFIG_CRYPTO_PUBLIC_KEYS := $(CONFIG_CRYPTO_PUBLIC_KEYS:"%"=%) + +$(obj)/public-keys.h: FORCE + $(call cmd,public_keys,$(CONFIG_CRYPTO_PUBLIC_KEYS)) -$(obj)/rsa-keys.h: FORCE - $(call cmd,public_keys,$(CONFIG_CRYPTO_RSA_KEY)) endif
crypto/public-keys.c new file +39 -0
@@ -0,0 +1,39 @@ +#include <common.h> +#include <crypto/public_key.h> +#include <rsa.h> + +extern const struct public_key *const __public_keys_start; +extern const struct public_key *const __public_keys_end; + +static int init_public_keys (void ) +{ +const struct public_key *const *iter; +int ret; + +for (iter = &__public_keys_start; iter != &__public_keys_end; iter++) { +struct rsa_public_key *rsa_key; + +switch ((*iter)->type) { +case PUBLIC_KEY_TYPE_RSA : + rsa_key =rsa_key_dup ((*iter)->rsa); +if (!rsa_key) +continue ; + + ret =rsa_key_add (rsa_key); +if (ret) +pr_err ("Cannot add rsa key: %pe\n" ,ERR_PTR (ret)); +break ; +default : +pr_err ("Ignoring unknown key type %u\n" , (*iter)->type); + } + + } + +return 0 ; +} + +device_initcall (init_public_keys); + +#ifdef CONFIG_CRYPTO_BUILTIN_KEYS +#include "public-keys.h" +#endif
crypto/rsa.c +2 -21
@@ -469,7 +469,7 @@ const struct rsa_public_key *rsa_get_key(const char *name)return NULL ; } -static int rsa_key_add (struct rsa_public_key *key) +int rsa_key_add (struct rsa_public_key *key) {if (rsa_get_key (key->key_name_hint))return -EEXIST ;
@@ -479,7 +479,7 @@ static int rsa_key_add(struct rsa_public_key *key)return 0 ; } -static struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key) +struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key) {struct rsa_public_key *new;
@@ -490,9 +490,6 @@ static struct rsa_public_key *rsa_key_dup(const struct rsa_public_key *key)return new; } -extern const struct rsa_public_key *const __rsa_keys_start; -extern const struct rsa_public_key *const __rsa_keys_end; -static void rsa_init_keys_of (void ) {struct device_node *sigs, *sig;
@@ -523,25 +520,9 @@ static void rsa_init_keys_of(void)static int rsa_init_keys (void ) { -const struct rsa_public_key *const *iter; -struct rsa_public_key *key; -int ret; - -for (iter = &__rsa_keys_start; iter != &__rsa_keys_end; iter++) { - key =rsa_key_dup (*iter); - ret =rsa_key_add (key); -if (ret) -pr_err ("Cannot add rsa key %s: %s\n" , - key->key_name_hint,strerror (-ret)); - } -rsa_init_keys_of ();return 0 ; }device_initcall (rsa_init_keys); - -#ifdef CONFIG_CRYPTO_RSA_BUILTIN_KEYS -#include "rsa-keys.h" -#endif
include/asm-generic/barebox.lds.h +5 -5
@@ -106,11 +106,11 @@#define BAREBOX_PCI_FIXUP #endif -#define BAREBOX_RSA_KEYS \ +#define BAREBOX_PUBLIC_KEYS \ STRUCT_ALIGN(); \ - __rsa_keys_start = .; \ - KEEP(*(.rsa_keys.rodata.*)); \ - __rsa_keys_end = .; \ + __public_keys_start = .; \ + KEEP(*(.public_keys.rodata.*)); \ + __public_keys_end = .; \#define BAREBOX_DEEP_PROBE \ STRUCT_ALIGN(); \
@@ -140,7 +140,7 @@BAREBOX_MAGICVARS \ BAREBOX_CLK_TABLE \BAREBOX_DTB \ - BAREBOX_RSA_KEYS \ + BAREBOX_PUBLIC_KEYS \BAREBOX_PCI_FIXUP \BAREBOX_DEEP_PROBE
include/crypto/public_key.h new file +20 -0
@@ -0,0 +1,20 @@ +#ifndef __CRYPTO_PUBLIC_KEY_H +#define __CRYPTO_PUBLIC_KEY_H + +struct rsa_public_key ; +struct ecdsa_public_key ; + +enum pulic_key_type { +PUBLIC_KEY_TYPE_RSA , +}; + +struct public_key { +enum pulic_key_type type; + +union { +struct rsa_public_key *rsa; +struct ecdsa_public_key *ecdsa; + }; +}; + +#endif /* __CRYPTO_PUBLIC_KEY_H */
include/rsa.h +16 -0
@@ -62,4 +62,20 @@ const struct rsa_public_key *rsa_key_next(const struct rsa_public_key *prev);#define for_each_rsa_key (key) \ for (key = rsa_key_next(NULL); key; key = rsa_key_next(key)) + +#ifdef CONFIG_CRYPTO_RSA +int rsa_key_add (struct rsa_public_key *key); +struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key); +#else +static inline int rsa_key_add (struct rsa_public_key *key) +{ +return -ENOSYS ; +} + +static inline struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key); +{ +return NULL ; +} +#endif +#endif
scripts/keytoc.c +14 -4
@@ -488,9 +488,14 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_nafprintf (outfilep,"\t.x = %s_x,\n" , key_name_c);fprintf (outfilep,"\t.y = %s_y,\n" , key_name_c);fprintf (outfilep,"};\n" ); -if (!standalone) -fprintf (outfilep,"\nstruct ecdsa_public_key *%s_ecdsa_p __attribute__((section(\".ecdsa_keys.rodata.%s\"))) = &%s;\n" , +if (!standalone) { +fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c); +fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_ECDSA,\n" ); +fprintf (outfilep,"\t.ecdsa = &%s,\n" , key_name_c); +fprintf (outfilep,"};" ); +fprintf (outfilep,"\nstruct public_key *%s_ecdsa_p __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n" , key_name_c, key_name_c, key_name_c); + } }return 0 ;
@@ -549,9 +554,14 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_namefprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"};\n" ); -if (!standalone) -fprintf (outfilep,"\nstruct rsa_public_key *%sp __attribute__((section(\".rsa_keys.rodata.%s\"))) = &%s;\n" , +if (!standalone) { +fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c); +fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_RSA,\n" ); +fprintf (outfilep,"\t.rsa = &%s,\n" , key_name_c); +fprintf (outfilep,"};" ); +fprintf (outfilep,"\nstruct public_key *%sp __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n" , key_name_c, key_name_c, key_name_c); + } }return 0 ;
Signature · 1 line
2.39.2
Re: [PATCH v4 09/16] crypto: rsa: encapsulate rsa keys in public keys struct
Quoted 10 lines · Sascha Hauer
This encapsulates struct
rsa_public_keyinto a structpublic_key. So far RSA keys are the only supported key type. With adding ECDSA keys we need a container struct so that we can add ECDSA keys using the same mechanisms.Also we rename
CONFIG_CRYPTO_RSA_KEYtoCONFIG_CRYPTO_PUBLIC_KEYSandCONFIG_CRYPTO_RSA_BUILTIN_KEYStoCONFIG_CRYPTO_BUILTIN_KEYSas these variables will be used for all types of keys, not only RSA keys.Signed-off-by Sascha Hauer <[email protected]>
But two comments below.
crypto/public-keys.c
Quoted 6 lines
crypto/public-keys.c new file +0
-0@@ -0,0 +1,39 @@
add a pr_fmt?
Quoted 29 lines
crypto/public-keys.c new file +29
-0+#include <common.h> +#include <crypto/public_key.h> +#include <rsa.h> + +extern const struct public_key *const __public_keys_start; +extern const struct public_key *const __public_keys_end; + +static int init_public_keys (void ) +{ +const struct public_key *const *iter; +int ret; + +for (iter = &__public_keys_start; iter != &__public_keys_end; iter++) { +struct rsa_public_key *rsa_key; + +switch ((*iter)->type) { +case PUBLIC_KEY_TYPE_RSA : + rsa_key =rsa_key_dup ((*iter)->rsa); +if (!rsa_key) +continue ; + + ret =rsa_key_add (rsa_key); +if (ret) +pr_err ("Cannot add rsa key: %pe\n" ,ERR_PTR (ret)); +break ; +default : +pr_err ("Ignoring unknown key type %u\n" , (*iter)->type); + } +
crypto/public-keys.c
Quoted 10 lines
crypto/public-keys.c new file +7
-2+ } + +return 0 ; +} + +device_initcall (init_public_keys); + -extern const struct rsa_public_key *const __rsa_keys_start; -extern const struct rsa_public_key *const __rsa_keys_end;
I know you are just moving these around, but defining these with [] is way less confusing IMO.
Thanks,
Ahmad
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH v4 09/16] crypto: rsa: encapsulate rsa keys in public keys struct
Quoted 62 lines · Ahmad Fatoum
Quoted 10 lines · Sascha Hauer
This encapsulates struct
rsa_public_keyinto a structpublic_key. So far RSA keys are the only supported key type. With adding ECDSA keys we need a container struct so that we can add ECDSA keys using the same mechanisms.Also we rename
CONFIG_CRYPTO_RSA_KEYtoCONFIG_CRYPTO_PUBLIC_KEYSandCONFIG_CRYPTO_RSA_BUILTIN_KEYStoCONFIG_CRYPTO_BUILTIN_KEYSas these variables will be used for all types of keys, not only RSA keys.Signed-off-by Sascha Hauer <[email protected]>Reviewed-by Ahmad Fatoum <[email protected]>But two comments below.
crypto/public-keys.c
Quoted 6 lines
crypto/public-keys.c new file +0
-0@@ -0,0 +1,39 @@add a
pr_fmt?Quoted 36 lines
crypto/public-keys.c new file +36
-0+#include <common.h> +#include <crypto/public_key.h> +#include <rsa.h> + +extern const struct public_key *const __public_keys_start; +extern const struct public_key *const __public_keys_end; + +static int init_public_keys (void ) +{ +const struct public_key *const *iter; +int ret; + +for (iter = &__public_keys_start; iter != &__public_keys_end; iter++) { +struct rsa_public_key *rsa_key; + +switch ((*iter)->type) { +case PUBLIC_KEY_TYPE_RSA : + rsa_key =rsa_key_dup ((*iter)->rsa); +if (!rsa_key) +continue ; + + ret =rsa_key_add (rsa_key); +if (ret) +pr_err ("Cannot add rsa key: %pe\n" ,ERR_PTR (ret)); +break ; +default : +pr_err ("Ignoring unknown key type %u\n" , (*iter)->type); + } + + } + +return 0 ; +} + +device_initcall (init_public_keys); +
Quoted 5 lines
crypto/public-keys.c
Quoted 2 lines
crypto/public-keys.c new file +0
-2-extern const struct rsa_public_key *const __rsa_keys_start; -extern const struct rsa_public_key *const __rsa_keys_end;I know you are just moving these around, but defining these with [] is way less confusing IMO.
This is changed in 12/16.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 10/16 crypto: add public_key functions
In reply to Sascha HauerNow that we have a struct public_key as a general container for keys create and use functions making use of it. Move the list from struct rsa_public_key to struct public_key, add public_key_verify() and use it instead of rsa_verify(), move key_name_hint to struct public_key.
With this we do not need to bother the FIT image code when adding support for ECDSA keys.
--- common/image-fit.c | 20 ++++---- crypto/public-keys.c | 92 ++++++++++++++++++++++++++++++------- crypto/rsa.c | 74 +++++++++-------------------- include/crypto/public_key.h | 15 ++++++ include/rsa.h | 16 +------ scripts/keytoc.c | 3 +- 6 files changed, 126 insertions(+), 94 deletions(-)
common/image-fit.c +10 -10
@@ -20,7 +20,7 @@#include <errno.h> #include <linux/err.h> #include <stringlist.h> -#include <rsa.h> +#include <crypto/public_key.h> #include <uncompress.h> #include <image-fit.h>
@@ -253,10 +253,10 @@ static struct digest *fit_alloc_digest(struct device_node *sig_node,return digest; } -static int fit_check_rsa_signature (struct device_node *sig_node, -enum hash_algo algo,void *hash) +static int fit_check_signature (struct device_node *sig_node, +enum hash_algo algo,void *hash) { -const struct rsa_public_key *key; +const struct public_key *key;const char *key_name =NULL ;int sig_len;const char *sig_value;
@@ -270,19 +270,19 @@ static int fit_check_rsa_signature(struct device_node *sig_node,of_property_read_string (sig_node,"key-name-hint" , &key_name);if (key_name) { - key =rsa_get_key (key_name); + key =public_key_get (key_name);if (key) { - ret =rsa_verify (key, sig_value, sig_len, hash, algo); + ret =public_key_verify (key, sig_value, sig_len, hash, algo);if (!ret) goto ok; } } -for_each_rsa_key (key) { +for_each_public_key (key) {if (key_name && !strcmp (key->key_name_hint, key_name))continue ; - ret =rsa_verify (key, sig_value, sig_len, hash, algo); + ret =public_key_verify (key, sig_value, sig_len, hash, algo);if (!ret) goto ok; }
@@ -341,7 +341,7 @@ static int fit_verify_signature(struct device_node *sig_node, const void *fit) hash =xzalloc (digest_length (digest));digest_final (digest, hash); - ret =fit_check_rsa_signature (sig_node, algo, hash); + ret =fit_check_signature (sig_node, algo, hash);if (ret) goto out_free_hash;
@@ -464,7 +464,7 @@ static int fit_image_verify_signature(struct fit_handle *handle, hash =xzalloc (digest_length (digest));digest_final (digest, hash); - ret =fit_check_rsa_signature (sig_node, algo, hash); + ret =fit_check_signature (sig_node, algo, hash);free (hash);
crypto/public-keys.c +76 -16
107 lines not on this page · raw message
crypto/rsa.c +22 -52
147 lines not on this page · raw message
include/crypto/public_key.h +15 -0
@@ -1,6 +1,8 @@#ifndef __CRYPTO_PUBLIC_KEY_H#define __CRYPTO_PUBLIC_KEY_H +#include <digest.h> +struct rsa_public_key ;struct ecdsa_public_key ;
@@ -10,6 +12,8 @@ enum pulic_key_type {struct public_key {enum pulic_key_type type; +struct list_head list; +char *key_name_hint;union {struct rsa_public_key *rsa;
@@ -17,4 +21,15 @@ struct public_key { }; }; +int public_key_add (struct public_key *key); +const struct public_key *public_key_get (const char *name); +const struct public_key *public_key_next (const struct public_key *prev); + +#define for_each_public_key (key) \ + for (key = public_key_next(NULL); key; key = public_key_next(key)) + +int public_key_verify (const struct public_key *key,const uint8_t *sig, +const uint32_t sig_len,const uint8_t *hash, +enum hash_algo algo); +#endif /* __CRYPTO_PUBLIC_KEY_H */
include/rsa.h +1 -15
@@ -29,8 +29,6 @@ struct rsa_public_key {uint32_t *modulus;/* modulus as little endian array */ uint32_t *rr;/* R^2 as little endian array */ uint64_t exponent;/* public exponent */ -char *key_name_hint; -struct list_head list; };/**
@@ -54,24 +52,12 @@ int rsa_verify(const struct rsa_public_key *key, const uint8_t *sig,struct device_node ; -struct rsa_public_key *rsa_of_read_key (struct device_node *node); +struct public_key *rsa_of_read_key (struct device_node *node);void rsa_key_free (struct rsa_public_key *key); -const struct rsa_public_key *rsa_get_key (const char *name); - -const struct rsa_public_key *rsa_key_next (const struct rsa_public_key *prev); - -#define for_each_rsa_key (key) \ - for (key = rsa_key_next(NULL); key; key = rsa_key_next(key))#ifdef CONFIG_CRYPTO_RSA -int rsa_key_add (struct rsa_public_key *key);struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key);#else -static inline int rsa_key_add (struct rsa_public_key *key) -{ -return -ENOSYS ; -} -static inline struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key); {return NULL ;
scripts/keytoc.c +2 -1
@@ -491,6 +491,7 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_naif (!standalone) {fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c);fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_ECDSA,\n" ); +fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"\t.ecdsa = &%s,\n" , key_name_c);fprintf (outfilep,"};" ); fprintf(outfilep, "\nstruct public_key *%s_ecdsa_p __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n",
@@ -551,12 +552,12 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_namefprintf (outfilep,"\t.modulus = %s_modulus,\n" , key_name_c);fprintf (outfilep,"\t.rr = %s_rr,\n" , key_name_c);fprintf (outfilep,"\t.exponent = 0x%0lx,\n" , exponent); -fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"};\n" );if (!standalone) {fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c);fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_RSA,\n" ); +fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"\t.rsa = &%s,\n" , key_name_c);fprintf (outfilep,"};" ); fprintf(outfilep, "\nstruct public_key *%sp __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n",
Signature · 1 line
2.39.2
Re: [PATCH v4 10/16] crypto: add public_key functions
Quoted 9 lines · Sascha Hauer
Now that we have a struct
public_keyas a general container for keys create and use functions making use of it. Move the list from structrsa_public_keyto structpublic_key, addpublic_key_verify()and use it instead ofrsa_verify(), movekey_name_hintto structpublic_key.With this we do not need to bother the FIT image code when adding support for ECDSA keys.
Signed-off-by Sascha Hauer <[email protected]>
Quoted 448 lines
--- common/image-fit.c | 20 ++++---- crypto/public-keys.c | 92 ++++++++++++++++++++++++++++++------- crypto/rsa.c | 74 +++++++++-------------------- include/crypto/public_key.h | 15 ++++++ include/rsa.h | 16 +------ scripts/keytoc.c | 3 +- 6 files changed, 126 insertions(+), 94 deletions(-)common/image-fit.c +10
-10@@ -20,7 +20,7 @@#include <errno.h> #include <linux/err.h> #include <stringlist.h> -#include <rsa.h> +#include <crypto/public_key.h> #include <uncompress.h> #include <image-fit.h> @@ -253,10 +253,10 @@ static struct digest *fit_alloc_digest(struct device_node *sig_node,return digest; } -static int fit_check_rsa_signature (struct device_node *sig_node, -enum hash_algo algo,void *hash) +static int fit_check_signature (struct device_node *sig_node, +enum hash_algo algo,void *hash) { -const struct rsa_public_key *key; +const struct public_key *key;const char *key_name =NULL ;int sig_len;const char *sig_value;@@ -270,19 +270,19 @@ static int fit_check_rsa_signature(struct device_node *sig_node,of_property_read_string (sig_node,"key-name-hint" , &key_name);if (key_name) { - key =rsa_get_key (key_name); + key =public_key_get (key_name);if (key) { - ret =rsa_verify (key, sig_value, sig_len, hash, algo); + ret =public_key_verify (key, sig_value, sig_len, hash, algo);if (!ret) goto ok; } } -for_each_rsa_key (key) { +for_each_public_key (key) {if (key_name && !strcmp (key->key_name_hint, key_name))continue ; - ret =rsa_verify (key, sig_value, sig_len, hash, algo); + ret =public_key_verify (key, sig_value, sig_len, hash, algo);if (!ret) goto ok; }@@ -341,7 +341,7 @@ static int fit_verify_signature(struct device_node *sig_node, const void *fit) hash =xzalloc (digest_length (digest));digest_final (digest, hash); - ret =fit_check_rsa_signature (sig_node, algo, hash); + ret =fit_check_signature (sig_node, algo, hash);if (ret) goto out_free_hash;@@ -464,7 +464,7 @@ static int fit_image_verify_signature(struct fit_handle *handle, hash =xzalloc (digest_length (digest));digest_final (digest, hash); - ret =fit_check_rsa_signature (sig_node, algo, hash); + ret =fit_check_signature (sig_node, algo, hash);free (hash);crypto/public-keys.c +76
-16@@ -2,31 +2,91 @@#include <crypto/public_key.h> #include <rsa.h> +static LIST_HEAD (public_keys); + +const struct public_key *public_key_next (const struct public_key *prev) +{ + prev =list_prepare_entry (prev, &public_keys, list); +list_for_each_entry_continue (prev, &public_keys, list) +return prev; + +return NULL ; +} + +const struct public_key *public_key_get (const char *name) +{ +const struct public_key *key; + +list_for_each_entry (key, &public_keys, list) { +if (!strcmp (key->key_name_hint, name)) +return key; + } + +return NULL ; +} + +int public_key_add (struct public_key *key) +{ +if (public_key_get (key->key_name_hint)) +return -EEXIST ; + +list_add_tail (&key->list, &public_keys); + +return 0 ; +} + +static struct public_key *public_key_dup (const struct public_key *key) +{ +struct public_key *k =xzalloc (sizeof (*k)); + + k->type = key->type; +if (key->key_name_hint) + k->key_name_hint =xstrdup (key->key_name_hint); + +switch (key->type) { +case PUBLIC_KEY_TYPE_RSA : + k->rsa =rsa_key_dup (key->rsa); +if (!k->rsa) + goto err; +break ; +default : + goto err; + } + +return k; +err: +free (k->key_name_hint); +free (k); + +return NULL ; +} + +int public_key_verify (const struct public_key *key,const uint8_t *sig, +const uint32_t sig_len,const uint8_t *hash, +enum hash_algo algo) +{ +switch (key->type) { +case PUBLIC_KEY_TYPE_RSA : +return rsa_verify (key->rsa, sig, sig_len, hash, algo); + } + +return -ENOKEY ; +} +extern const struct public_key *const __public_keys_start;extern const struct public_key *const __public_keys_end;static int init_public_keys (void ) {const struct public_key *const *iter; -int ret;for (iter = &__public_keys_start; iter != &__public_keys_end; iter++) { -struct rsa_public_key *rsa_key; - -switch ((*iter)->type) { -case PUBLIC_KEY_TYPE_RSA : - rsa_key =rsa_key_dup ((*iter)->rsa); -if (!rsa_key) -continue ; - - ret =rsa_key_add (rsa_key); -if (ret) -pr_err ("Cannot add rsa key: %pe\n" ,ERR_PTR (ret)); -break ; -default : -pr_err ("Ignoring unknown key type %u\n" , (*iter)->type); - } +struct public_key *key =public_key_dup (*iter); + +if (!key) +continue ; +public_key_add (key); }return 0 ;crypto/rsa.c +22
-52@@ -15,6 +15,7 @@#include <asm/byteorder.h> #include <errno.h> #include <rsa.h> +#include <crypto/public_key.h> #include <asm/unaligned.h> #define UINT64_MULT32 (v, multby) (((uint64_t)(v)) * ((uint32_t)(multby)))@@ -380,105 +381,74 @@ static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len) dst[i] =fdt32_to_cpu (src[len -1 - i]); } -struct rsa_public_key *rsa_of_read_key (struct device_node *node) +struct public_key *rsa_of_read_key (struct device_node *node) {const void *modulus, *rr;const uint64_t *public_exponent;int length; -struct rsa_public_key *key; +struct public_key *key; +struct rsa_public_key *rsa;int err;if (strncmp (node->name,"key-" ,4 ))return ERR_PTR (-EINVAL ); key =xzalloc (sizeof (*key)); + rsa = key->rsa =xzalloc (sizeof (*rsa)); key->key_name_hint =xstrdup (node->name +4 ); -of_property_read_u32 (node,"rsa,num-bits" , &key->len); -of_property_read_u32 (node,"rsa,n0-inverse" , &key->n0inv); +of_property_read_u32 (node,"rsa,num-bits" , &rsa->len); +of_property_read_u32 (node,"rsa,n0-inverse" , &rsa->n0inv); public_exponent =of_get_property (node,"rsa,exponent" , &length);if (!public_exponent || length <sizeof (*public_exponent)) - key->exponent =RSA_DEFAULT_PUBEXP ; + rsa->exponent =RSA_DEFAULT_PUBEXP ;else - key->exponent =fdt64_to_cpu (*public_exponent); + rsa->exponent =fdt64_to_cpu (*public_exponent); modulus =of_get_property (node,"rsa,modulus" ,NULL ); rr =of_get_property (node,"rsa,r-squared" ,NULL ); -if (!key->len || !modulus || !rr) { +if (!rsa->len || !modulus || !rr) {pr_debug ("%s: Missing RSA key info" , __func__); err = -EFAULT ; goto out; }/* Sanity check for stack size */ -if (key->len >RSA_MAX_KEY_BITS || key->len <RSA_MIN_KEY_BITS ) { +if (rsa->len >RSA_MAX_KEY_BITS || rsa->len <RSA_MIN_KEY_BITS ) {pr_debug ("RSA key bits %u outside allowed range %d..%d\n" , - key->len,RSA_MIN_KEY_BITS ,RSA_MAX_KEY_BITS ); + rsa->len,RSA_MIN_KEY_BITS ,RSA_MAX_KEY_BITS ); err = -EFAULT ; goto out; } - key->len /=sizeof (uint32_t ) *8 ; + rsa->len /=sizeof (uint32_t ) *8 ; - key->modulus =xzalloc (RSA_MAX_KEY_BITS /8 ); - key->rr =xzalloc (RSA_MAX_KEY_BITS /8 ); + rsa->modulus =xzalloc (RSA_MAX_KEY_BITS /8 ); + rsa->rr =xzalloc (RSA_MAX_KEY_BITS /8 ); -rsa_convert_big_endian (key->modulus, modulus, key->len); -rsa_convert_big_endian (key->rr, rr, key->len); +rsa_convert_big_endian (rsa->modulus, modulus, rsa->len); +rsa_convert_big_endian (rsa->rr, rr, rsa->len); err =0 ; out: -if (err) +if (err) {free (key); +free (rsa); + }return err ?ERR_PTR (err) : key; }void rsa_key_free (struct rsa_public_key *key) { -list_del (&key->list); -free (key->modulus);free (key->rr);free (key); } -static LIST_HEAD (rsa_keys); - -const struct rsa_public_key *rsa_key_next (const struct rsa_public_key *prev) -{ - prev =list_prepare_entry (prev, &rsa_keys, list); -list_for_each_entry_continue (prev, &rsa_keys, list) -return prev; - -return NULL ; -} - -const struct rsa_public_key *rsa_get_key (const char *name) -{ -const struct rsa_public_key *key; - -list_for_each_entry (key, &rsa_keys, list) { -if (!strcmp (key->key_name_hint, name)) -return key; - } - -return NULL ; -} - -int rsa_key_add (struct rsa_public_key *key) -{ -if (rsa_get_key (key->key_name_hint)) -return -EEXIST ; - -list_add_tail (&key->list, &rsa_keys); - -return 0 ; -} -struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key) {struct rsa_public_key *new;@@ -493,7 +463,7 @@ struct rsa_public_key *rsa_key_dup(const struct rsa_public_key *key)static void rsa_init_keys_of (void ) {struct device_node *sigs, *sig; -struct rsa_public_key *key; +struct public_key *key;int ret;if (!IS_ENABLED (CONFIG_OFTREE ))@@ -511,7 +481,7 @@ static void rsa_init_keys_of(void)continue ; } - ret =rsa_key_add (key); + ret =public_key_add (key);if (ret)pr_err ("Cannot add rsa key %s: %s\n" , key->key_name_hint,strerror (-ret));include/crypto/public_key.h +15
-0@@ -1,6 +1,8 @@#ifndef __CRYPTO_PUBLIC_KEY_H#define __CRYPTO_PUBLIC_KEY_H +#include <digest.h> +struct rsa_public_key ;struct ecdsa_public_key ;@@ -10,6 +12,8 @@ enum pulic_key_type {struct public_key {enum pulic_key_type type; +struct list_head list; +char *key_name_hint;union {struct rsa_public_key *rsa;@@ -17,4 +21,15 @@ struct public_key { }; }; +int public_key_add (struct public_key *key); +const struct public_key *public_key_get (const char *name); +const struct public_key *public_key_next (const struct public_key *prev); + +#define for_each_public_key (key) \ + for (key = public_key_next(NULL); key; key = public_key_next(key)) + +int public_key_verify (const struct public_key *key,const uint8_t *sig, +const uint32_t sig_len,const uint8_t *hash, +enum hash_algo algo); +#endif /* __CRYPTO_PUBLIC_KEY_H */ include/rsa.h +1
-15@@ -29,8 +29,6 @@ struct rsa_public_key {uint32_t *modulus;/* modulus as little endian array */ uint32_t *rr;/* R^2 as little endian array */ uint64_t exponent;/* public exponent */ -char *key_name_hint; -struct list_head list; };/** @@ -54,24 +52,12 @@ int rsa_verify(const struct rsa_public_key *key, const uint8_t *sig,struct device_node ; -struct rsa_public_key *rsa_of_read_key (struct device_node *node); +struct public_key *rsa_of_read_key (struct device_node *node);void rsa_key_free (struct rsa_public_key *key); -const struct rsa_public_key *rsa_get_key (const char *name); - -const struct rsa_public_key *rsa_key_next (const struct rsa_public_key *prev); - -#define for_each_rsa_key (key) \ - for (key = rsa_key_next(NULL); key; key = rsa_key_next(key))#ifdef CONFIG_CRYPTO_RSA -int rsa_key_add (struct rsa_public_key *key);struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key);#else -static inline int rsa_key_add (struct rsa_public_key *key) -{ -return -ENOSYS ; -} -static inline struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key); {return NULL ;scripts/keytoc.c +2
-1@@ -491,6 +491,7 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_naif (!standalone) {fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c);fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_ECDSA,\n" ); +fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"\t.ecdsa = &%s,\n" , key_name_c);fprintf (outfilep,"};" ); fprintf(outfilep, "\nstruct public_key *%s_ecdsa_p __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n",@@ -551,12 +552,12 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_namefprintf (outfilep,"\t.modulus = %s_modulus,\n" , key_name_c);fprintf (outfilep,"\t.rr = %s_rr,\n" , key_name_c);fprintf (outfilep,"\t.exponent = 0x%0lx,\n" , exponent); -fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"};\n" );if (!standalone) {fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c);fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_RSA,\n" ); +fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"\t.rsa = &%s,\n" , key_name_c);fprintf (outfilep,"};" ); fprintf(outfilep, "\nstruct public_key *%sp __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n",
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 11/16 crypto: builtin_keys: Allow to specify multiple keys in CONFIG_CRYPTO_PUBLIC_KEYS
In reply to Sascha HauerThis adds the missing pieces to make CONFIG_CRYPTO_PUBLIC_KEYS a list of keys rather than a single key only.
We have to remove the quotes from the key argument in cmd_keys to pass the keys as multiple arguments to keytoc.
For removing the quotes from CONFIG_CRYPTO_PUBLIC_KEYS "%"=% no longer matches when the string contains multiple words, so we utilize shell to remove the quotes.
--- crypto/Kconfig | 11 ++++++----- crypto/Makefile | 2 +- scripts/Makefile.lib | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-)
crypto/Kconfig +6 -5
@@ -126,11 +126,12 @@ config CRYPTO_PUBLIC_KEYS depends on CRYPTO_BUILTIN_KEYS string "public keys to compile in" help - This option should be a filename of a PEM-formatted file containing - X.509 certificates to be included into barebox. If the string starts - with "pkcs11:" it is interpreted as a PKCS#11 URI rather than a file. - If the string starts with a <hint>: prefix, <hint> is used as a key - name hint to find a key without iterating over all keys. + This option should be a space separated list of filenames of + PEM-formatted files containing X.509 certificates to be included into + barebox. If an entry starts with "pkcs11:" it is interpreted as a + PKCS#11 URI rather than a file. If an entry starts with a <hint>: + prefix, <hint> is used as a key name hint to find a key without + iterating over all keys. This avoids the mkimage dependency of CONFIG_BOOTM_FITIMAGE_PUBKEY at the cost of an openssl build-time dependency.
crypto/Makefile +1 -1
@@ -28,7 +28,7 @@ ifdef CONFIG_CRYPTO_BUILTIN_KEYS $(obj)/public-keys.o: $(obj)/public-keys.h -CONFIG_CRYPTO_PUBLIC_KEYS := $(CONFIG_CRYPTO_PUBLIC_KEYS:"%"=%) +CONFIG_CRYPTO_PUBLIC_KEYS := $(shell echo $(CONFIG_CRYPTO_PUBLIC_KEYS)) $(obj)/public-keys.h: FORCE $(call cmd,public_keys,$(CONFIG_CRYPTO_PUBLIC_KEYS))
scripts/Makefile.lib +1 -1
@@ -614,7 +614,7 @@ quiet_cmd_b64dec = B64DEC $@ # target file. quiet_cmd_public_keys = KEY $@ cmd_public_keys = \ - $(objtree)/scripts/keytoc -o [email protected] "$(2)" $(3) && \ + $(objtree)/scripts/keytoc -o [email protected] $(2) $(3) && \ if cmp -s [email protected] $@; then \ rm [email protected]; \ else \
Signature · 1 line
2.39.2
Re: [PATCH v4 11/16] crypto: builtin_keys: Allow to specify multiple keys in CONFIG_CRYPTO_PUBLIC_KEYS
Quoted 57 lines · Sascha Hauer
This adds the missing pieces to make
CONFIG_CRYPTO_PUBLIC_KEYSa list of keys rather than a single key only.We have to remove the quotes from the key argument in
cmd_keysto pass the keys as multiple arguments to keytoc.For removing the quotes from
CONFIG_CRYPTO_PUBLIC_KEYS"%"=% no longer matches when the string contains multiple words, so we utilize shell to remove the quotes.Signed-off-by Sascha Hauer <[email protected]>--- crypto/Kconfig | 11 ++++++----- crypto/Makefile | 2 +- scripts/Makefile.lib | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-)crypto/Kconfig +6
-5@@ -126,11 +126,12 @@ config CRYPTO_PUBLIC_KEYS depends on CRYPTO_BUILTIN_KEYS string "public keys to compile in" help - This option should be a filename of a PEM-formatted file containing - X.509 certificates to be included into barebox. If the string starts - with "pkcs11:" it is interpreted as a PKCS#11 URI rather than a file. - If the string starts with a <hint>: prefix, <hint> is used as a key - name hint to find a key without iterating over all keys. + This option should be a space separated list of filenames of + PEM-formatted files containing X.509 certificates to be included into + barebox. If an entry starts with "pkcs11:" it is interpreted as a + PKCS#11 URI rather than a file. If an entry starts with a <hint>: + prefix, <hint> is used as a key name hint to find a key without + iterating over all keys. This avoids the mkimage dependency of CONFIG_BOOTM_FITIMAGE_PUBKEY at the cost of an openssl build-time dependency.crypto/Makefile +1
-1@@ -28,7 +28,7 @@ ifdef CONFIG_CRYPTO_BUILTIN_KEYS $(obj)/public-keys.o: $(obj)/public-keys.h -CONFIG_CRYPTO_PUBLIC_KEYS := $(CONFIG_CRYPTO_PUBLIC_KEYS:"%"=%) +CONFIG_CRYPTO_PUBLIC_KEYS := $(shell echo $(CONFIG_CRYPTO_PUBLIC_KEYS)) $(obj)/public-keys.h: FORCE $(call cmd,public_keys,$(CONFIG_CRYPTO_PUBLIC_KEYS))scripts/Makefile.lib +0
-0
scripts/Makefile.lib quiet_cmd_b64dec = B64DEC $@ · line 617
Quoted 5 lines
scripts/Makefile.lib +1
-1@@ -614,7 +614,7 @@ quiet_cmd_b64dec = B64DEC $@ # target file. quiet_cmd_public_keys = KEY $@ cmd_public_keys = \ - $(objtree)/scripts/keytoc -o [email protected] "$(2)" $(3) && \ + $(objtree)/scripts/keytoc -o [email protected] $(2) $(3) && \
This doesn't work with pkcs11: uris. These may contain semicolons which must be quoted from the shell. We must quote the the words in CONFIG_CRYPTO_PUBLIC_KEYS though, not the whole string. So what we can do is:
CONFIG_CRYPTO_PUBLIC_KEYS := $(foreach d,$(CONFIG_CRYPTO_PUBLIC_KEYS),"$(d)")
Sascha
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 12/16 crypto: public-keys: use array of public_keys
In reply to Sascha HauerInstead of collecting the public keys directly in a section, we used to collect pointers to the public keys. This indirection is unnecessary, so drop it and put the keys directly into a section.
--- crypto/public-keys.c | 10 +++++----- scripts/keytoc.c | 12 ++++-------- 2 files changed, 9 insertions(+), 13 deletions(-)
crypto/public-keys.c +5 -5
@@ -73,15 +73,15 @@ int public_key_verify(const struct public_key *key, const uint8_t *sig,return -ENOKEY ; } -extern const struct public_key *const __public_keys_start; -extern const struct public_key *const __public_keys_end; +extern const struct public_key __public_keys_start[]; +extern const struct public_key __public_keys_end[];static int init_public_keys (void ) { -const struct public_key *const *iter; +const struct public_key *iter; -for (iter = &__public_keys_start; iter != &__public_keys_end; iter++) { -struct public_key *key =public_key_dup (*iter); +for (iter = __public_keys_start; iter != __public_keys_end; iter++) { +struct public_key *key =public_key_dup (iter);if (!key)continue ;
scripts/keytoc.c +4 -8
@@ -489,13 +489,11 @@ static int gen_key_ecdsa(EVP_PKEY *key, const char *key_name, const char *key_nafprintf (outfilep,"\t.y = %s_y,\n" , key_name_c);fprintf (outfilep,"};\n" );if (!standalone) { -fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c); +fprintf (outfilep,"\nstruct public_key __attribute__((section(\".public_keys.rodata.%s\"))) %s_public_key = {\n" , key_name_c, key_name_c);fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_ECDSA,\n" );fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"\t.ecdsa = &%s,\n" , key_name_c); -fprintf (outfilep,"};" ); -fprintf (outfilep,"\nstruct public_key *%s_ecdsa_p __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n" , - key_name_c, key_name_c, key_name_c); +fprintf (outfilep,"};\n" ); } }
@@ -555,13 +553,11 @@ static int gen_key_rsa(EVP_PKEY *key, const char *key_name, const char *key_namefprintf (outfilep,"};\n" );if (!standalone) { -fprintf (outfilep,"\nstatic struct public_key %s_public_key = {\n" , key_name_c); +fprintf (outfilep,"\nstruct public_key __attribute__((section(\".public_keys.rodata.%s\"))) %s_public_key = {\n" , key_name_c, key_name_c);fprintf (outfilep,"\t.type = PUBLIC_KEY_TYPE_RSA,\n" );fprintf (outfilep,"\t.key_name_hint = \"%s\",\n" , key_name);fprintf (outfilep,"\t.rsa = &%s,\n" , key_name_c); -fprintf (outfilep,"};" ); -fprintf (outfilep,"\nstruct public_key *%sp __attribute__((section(\".public_keys.rodata.%s\"))) = &%s_public_key;\n" , - key_name_c, key_name_c, key_name_c); +fprintf (outfilep,"};\n" ); } }
Signature · 1 line
2.39.2
PATCH v4 13/16 crypto: rsa: create static inline wrapper for rsa_verify()
In reply to Sascha Hauerrsa_verify() is called from generic code, so provide a static inline no-op wrapper used when RSA support is disabled.
--- include/rsa.h | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
include/rsa.h +17 -10
@@ -31,6 +31,15 @@ struct rsa_public_key {uint64_t exponent;/* public exponent */ }; +/* This is the maximum signature length that we support, in bits */ +#define RSA_MAX_SIG_BITS 4096 + +struct device_node ; + +struct public_key *rsa_of_read_key (struct device_node *node); +void rsa_key_free (struct rsa_public_key *key); + +#ifdef CONFIG_CRYPTO_RSA /** * rsa_verify() - Verify a signature against some data *
@@ -47,18 +56,16 @@ int rsa_verify(const struct rsa_public_key *key, const uint8_t *sig, const uint32_t sig_len, const uint8_t *hash, enum hash_algo algo); -/* This is the maximum signature length that we support, in bits */ -#define RSA_MAX_SIG_BITS 4096 - -struct device_node ; - -struct public_key *rsa_of_read_key (struct device_node *node); -void rsa_key_free (struct rsa_public_key *key); - -#ifdef CONFIG_CRYPTO_RSA struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key);#else -static inline struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key); +static inline int rsa_verify (const struct rsa_public_key *key,const uint8_t *sig, +const uint32_t sig_len,const uint8_t *hash, +enum hash_algo algo) +{ +return -ENOSYS ; +} + +static inline struct rsa_public_key *rsa_key_dup (const struct rsa_public_key *key) {return NULL ; }
Signature · 1 line
2.39.2
Re: [PATCH v4 13/16] crypto: rsa: create static inline wrapper for rsa_verify()
Quoted 4 lines · Sascha Hauer
rsa_verify()is called from generic code, so provide a static inline no-op wrapper used when RSA support is disabled.Signed-off-by Sascha Hauer <[email protected]>
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 14/16 Add elliptic curve cryptography (ECC) helper functions
In reply to Sascha HauerThis ports the functions needed for supporting elliptic curve cryptography (ECC) from the Kernel. The code is taken from Linux-6.10 and mostly unchanged.
--- crypto/Kconfig | 3 + crypto/Makefile | 1 + crypto/ecc.c | 1661 +++++++++++++++++++++++++++++++++ crypto/ecc_curve_defs.h | 155 +++ include/crypto/ecc_curve.h | 62 ++ include/crypto/ecdh.h | 83 ++ include/crypto/internal/ecc.h | 278 ++++++ 7 files changed, 2243 insertions(+) create mode 100644 crypto/ecc.c create mode 100644 crypto/ecc_curve_defs.h create mode 100644 include/crypto/ecc_curve.h create mode 100644 include/crypto/ecdh.h create mode 100644 include/crypto/internal/ecc.h
crypto/Kconfig +3 -0
@@ -148,4 +148,7 @@ config JWT select BASE64 select CRYPTO_RSA +config CRYPTO_ECC + bool + endmenu
crypto/Makefile +1 -0
@@ -19,6 +19,7 @@ obj-$(CONFIG_CRYPTO_PBKDF2) += pbkdf2.o obj-$(CONFIG_CRYPTO_RSA) += rsa.o obj-$(CONFIG_CRYPTO_KEYSTORE) += keystore.o obj-$(CONFIG_CRYPTO_BUILTIN_KEYS) += public-keys.o +obj-$(CONFIG_CRYPTO_ECC) += ecc.o obj-$(CONFIG_JWT) += jwt.o
crypto/ecc.c new file +1661 -0
1,661 lines not on this page · raw message
crypto/ecc_curve_defs.h new file +155 -0
155 lines not on this page · raw message
include/crypto/ecc_curve.h new file +62 -0
62 lines not on this page · raw message
include/crypto/ecdh.h new file +83 -0
83 lines not on this page · raw message
include/crypto/internal/ecc.h new file +278 -0
278 lines not on this page · raw message
Signature · 1 line
2.39.2
Lukas Wunner
maintainerRe: [PATCH v4 14/16] Add elliptic curve cryptography (ECC) helper functions
Quoted 1 line · Sascha Hauer
+++
b/crypto/ecc.c
[...]
crypto/ecc.c line 434
Quoted 8 lines
crypto/ecc.c new file +8
-0+for (i = min; i <= k && i < ndigits; i++) { +uint128_t product; + + product =mul_64_64 (left[i], right[k - i]); + + r01 =add_128_128 (r01, product); + r2 += (r01.m_high < product.m_high); + }
Heads-up, this barebox code was copy-pasted from the kernel, which in turn copy-pasted it from Ken MacKay's micro-ecc library. The kernel version has a bug in carry handling which barebox inherited:
https://lore.kernel.org/r/[email protected]/
There might be further bugs that were fixed in the kernel but not in barebox.
Thanks,
Lukas
Re: [PATCH v4 14/16] Add elliptic curve cryptography (ECC) helper functions
Hello Lukas,
Quoted 9 lines · Lukas Wunner
Heads-up, this barebox code was copy-pasted from the kernel, which in turn copy-pasted it from Ken MacKay's micro-ecc library. The kernel version has a bug in carry handling which barebox inherited:
https://lore.kernel.org/r/[email protected]/
There might be further bugs that were fixed in the kernel but not in barebox.
Thank you for mentioning it. I've just sent a series that brings the file up to date with linux master, and will do this again once your linked kernel patch has landed.
Regards,
Jonas
Signature · 4 lines
Pengutronix e.K. | Jonas Rebmann | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
PATCH v4 15/16 crypto: add ECDSA support
In reply to Sascha HauerThis adds ECDSA signature verification support. The code is based on the Linux code as of Linux-6.10. The Linux code expects the key to be in ASN.1 encoded format. We don't need this in barebox as directly compile the x and y key values into the binary, so this is left out.
--- crypto/Kconfig | 4 ++ crypto/Makefile | 1 + crypto/ecdsa.c | 140 ++++++++++++++++++++++++++++++++++++ crypto/public-keys.c | 8 +++ include/crypto/public_key.h | 1 + include/ecdsa.h | 42 +++++++++++ 6 files changed, 196 insertions(+) create mode 100644 crypto/ecdsa.c create mode 100644 include/ecdsa.h
crypto/Kconfig +4 -0
@@ -151,4 +151,8 @@ config JWT config CRYPTO_ECC bool +config CRYPTO_ECDSA + bool "ECDSA support" + select CRYPTO_ECC + endmenu
crypto/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_CRYPTO_RSA) += rsa.o obj-$(CONFIG_CRYPTO_KEYSTORE) += keystore.o obj-$(CONFIG_CRYPTO_BUILTIN_KEYS) += public-keys.o obj-$(CONFIG_CRYPTO_ECC) += ecc.o +obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa.o obj-$(CONFIG_JWT) += jwt.o
crypto/ecdsa.c new file +140 -0
140 lines not on this page · raw message
crypto/public-keys.c +8 -0
@@ -1,6 +1,7 @@#include <common.h> #include <crypto/public_key.h> #include <rsa.h> +#include <ecdsa.h> static LIST_HEAD (public_keys);
@@ -49,6 +50,11 @@ static struct public_key *public_key_dup(const struct public_key *key)if (!k->rsa) goto err;break ; +case PUBLIC_KEY_TYPE_ECDSA : + k->ecdsa =ecdsa_key_dup (key->ecdsa); +if (!k->ecdsa) + goto err; +break ;default : goto err; }
@@ -68,6 +74,8 @@ int public_key_verify(const struct public_key *key, const uint8_t *sig,switch (key->type) {case PUBLIC_KEY_TYPE_RSA :return rsa_verify (key->rsa, sig, sig_len, hash, algo); +case PUBLIC_KEY_TYPE_ECDSA : +return ecdsa_verify (key->ecdsa, sig, sig_len, hash); }return -ENOKEY ;
include/crypto/public_key.h +1 -0
@@ -8,6 +8,7 @@ struct ecdsa_public_key;enum pulic_key_type {PUBLIC_KEY_TYPE_RSA , +PUBLIC_KEY_TYPE_ECDSA , };struct public_key {
include/ecdsa.h new file +42 -0
42 lines not on this page · raw message
Signature · 1 line
2.39.2
Re: [PATCH v4 15/16] crypto: add ECDSA support
Quoted 6 lines · Sascha Hauer
This adds ECDSA signature verification support. The code is based on the Linux code as of Linux-6.10. The Linux code expects the key to be in ASN.1 encoded format. We don't need this in barebox as directly compile the x and y key values into the binary, so this is left out.
Signed-off-by Sascha Hauer <[email protected]>
Some minor comments below.
crypto/public-keys.c line 4
Quoted 9 lines
crypto/public-keys.c +1
-0@@ -1,6 +1,7 @@#include <common.h> #include <crypto/public_key.h> #include <rsa.h> +#include <ecdsa.h>
We should perhaps move these two into crypto/ as well.
include/crypto/public_key.h struct ecdsa_public_key; · line 9
Quoted 7 lines
include/crypto/public_key.h +0
-0@@ -8,6 +8,7 @@ struct ecdsa_public_key;enum pulic_key_type {
s/pulic/public/
Quoted 11 lines
include/crypto/public_key.h +1
-0PUBLIC_KEY_TYPE_RSA , + PUBLIC_KEY_TYPE_ECDSA, }; struct public_key {include/ecdsa.h new file +0
-0
include/ecdsa.h line 3
Quoted 3 lines
include/ecdsa.h new file +3
-0@@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-only +#ifndef _ECDSA_H +#define _ECDSA_H
#include <linux/list.h>
#include <linux/types.h>
include/ecdsa.h line 11
Quoted 8 lines
include/ecdsa.h new file +8
-0+ +struct ecdsa_public_key { +const char *curve_name;/* Name of curve, e.g. "prime256v1" */ +const uint64_t *x;/* x coordinate of public key */ +const uint64_t *y;/* y coordinate of public key */ +unsigned int size_bits;/* key size in bits, derived from curve name */ +struct list_head list; +};
Cheers,
Ahmad
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v4 16/16 crypto: make RSA a visible option
In reply to Sascha HauerWith ECDSA support RSA is no longer the only option for FIT image verification. Make CONFIG_CRYPTO_RSA visible so that the user can choose. CONFIG_CRYPTO_RSA defaults to yes when FITIMAGE_SIGNATURE is selected so that existing configs continue to work.
--- common/Kconfig | 1 - crypto/Kconfig | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-)
common/Kconfig +0 -1
@@ -62,7 +62,6 @@ config FITIMAGE select DIGEST config FITIMAGE_SIGNATURE - select CRYPTO_RSA bool config LOGBUF
crypto/Kconfig +2 -1
@@ -116,7 +116,8 @@ config CRYPTO_PBKDF2 bool config CRYPTO_RSA - bool + bool "RSA support" + default y if FITIMAGE_SIGNATURE config CRYPTO_BUILTIN_KEYS bool "builtin keys"
Signature · 1 line
2.39.2
Sascha Hauer
AppliedQuoted 10 lines · Sascha Hauer
This series implements ECDSA signature verification for FIT images. The ECDSA code itself is taken from the Kernel. Currently only supported way to specify a ECDSA key is to compile it into the binary using
CONFIG_CRYPTO_PUBLIC_KEYS, taking it from a device tree is not yet supported.
Since v2 this series unifies the way public keys are passed to barebox. We now have a singleKconfigoption which takes a list of public keys, which can be either RSA or ECDSA keys.[...]
Applied, thanks!
[01/16] keytoc: remove ECDSA dts support
https://git.pengutronix.de/cgit/barebox/commit/?id=ea8da7c9f2bc (link may not be stable)
[02/16] keytoc: fail in case gen_key() fails
https://git.pengutronix.de/cgit/barebox/commit/?id=dcd40860f529 (link may not be stable)
[03/16] keytoc: fix ECDSA endianess problems
https://git.pengutronix.de/cgit/barebox/commit/?id=9932d1817b84 (link may not be stable)
[04/16] keytoc: remove duplicate __ENV__ check
https://git.pengutronix.de/cgit/barebox/commit/?id=7a0ced8632b5 (link may not be stable)
[05/16] crypto: Makefile: make simpler
https://git.pengutronix.de/cgit/barebox/commit/?id=099f1aed5c67 (link may not be stable)
[06/16] crypto/Makefile: Drop unnecessary dependencies
https://git.pengutronix.de/cgit/barebox/commit/?id=d0aa7e8fb1e2 (link may not be stable)
[07/16] keytoc: make key name hint optional
https://git.pengutronix.de/cgit/barebox/commit/?id=ed553b7d070c (link may not be stable)
[08/16] crypto: rsa: include key name hint into CONFIG_CRYPTO_RSA_KEY
https://git.pengutronix.de/cgit/barebox/commit/?id=93ccf51a40ff (link may not be stable)
[09/16] crypto: rsa: encapsulate rsa keys in public keys struct
https://git.pengutronix.de/cgit/barebox/commit/?id=b26a8b0a025c (link may not be stable)
[10/16] crypto: add public_key functions
https://git.pengutronix.de/cgit/barebox/commit/?id=724f48590768 (link may not be stable)
[11/16] crypto: builtin_keys: Allow to specify multiple keys in CONFIG_CRYPTO_PUBLIC_KEYS
https://git.pengutronix.de/cgit/barebox/commit/?id=13db5fdf2d54 (link may not be stable)
[12/16] crypto: public-keys: use array of public_keys
https://git.pengutronix.de/cgit/barebox/commit/?id=1eb1f1d2b885 (link may not be stable)
[13/16] crypto: rsa: create static inline wrapper for rsa_verify()
https://git.pengutronix.de/cgit/barebox/commit/?id=5ace4df43844 (link may not be stable)
[14/16] Add elliptic curve cryptography (ECC) helper functions
https://git.pengutronix.de/cgit/barebox/commit/?id=cdc6830e3121 (link may not be stable)
[15/16] crypto: add ECDSA support
https://git.pengutronix.de/cgit/barebox/commit/?id=1a3214bd3eb3 (link may not be stable)
[16/16] crypto: make RSA a visible option
https://git.pengutronix.de/cgit/barebox/commit/?id=8e1de73767fd (link may not be stable)
Best regards,
Signature · 1 line
Sascha Hauer <[email protected]>
Quoted 11 lines · Sascha Hauer
Quoted 9 lines · Sascha Hauer
This series implements ECDSA signature verification for FIT images. The ECDSA code itself is taken from the Kernel. Currently only supported way to specify a ECDSA key is to compile it into the binary using
CONFIG_CRYPTO_PUBLIC_KEYS, taking it from a device tree is not yet supported.
Since v2 this series unifies the way public keys are passed to barebox. We now have a singleKconfigoption which takes a list of public keys, which can be either RSA or ECDSA keys.
Quoted 3 lines
Quoted 1 line
[...]
Applied, thanks!
With afas comments integrated of course.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |