From 0c1d74fda7c0063eeca4d8d9fa8674e6ec2ef685 Mon Sep 17 00:00:00 2001 From: Andrew Duda Date: Tue, 8 Nov 2016 18:53:41 +0000 Subject: [PATCH] image: Add crypto_algo struct for RSA info Cut down on the repetition of algorithm information by defining separate checksum and crypto structs. image_sig_algos are now simply pairs of unique checksum and crypto algos. Signed-off-by: Andrew Duda Signed-off-by: aduda Reviewed-by: Simon Glass --- common/image-sig.c | 46 +++++++++++++++++++++++----------------------- include/image.h | 9 +++++++-- lib/rsa/rsa-verify.c | 19 +++++++++++-------- tools/image-host.c | 9 +++++---- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/common/image-sig.c b/common/image-sig.c index 008d2c5..8b4314d 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -36,7 +36,6 @@ struct checksum_algo checksum_algos[] = { SHA1_SUM_LEN, SHA1_DER_LEN, sha1_der_prefix, - RSA2048_BYTES, #if IMAGE_ENABLE_SIGN EVP_sha1, #endif @@ -47,22 +46,28 @@ struct checksum_algo checksum_algos[] = { SHA256_SUM_LEN, SHA256_DER_LEN, sha256_der_prefix, - RSA2048_BYTES, #if IMAGE_ENABLE_SIGN EVP_sha256, #endif hash_calculate, + } + +}; + +struct crypto_algo crypto_algos[] = { + { + "rsa2048", + RSA2048_BYTES, + rsa_sign, + rsa_add_verify_data, + rsa_verify, }, { - "sha256", - SHA256_SUM_LEN, - SHA256_DER_LEN, - sha256_der_prefix, + "rsa4096", RSA4096_BYTES, -#if IMAGE_ENABLE_SIGN - EVP_sha256, -#endif - hash_calculate, + rsa_sign, + rsa_add_verify_data, + rsa_verify, } }; @@ -70,24 +75,18 @@ struct checksum_algo checksum_algos[] = { struct image_sig_algo image_sig_algos[] = { { "sha1,rsa2048", - rsa_sign, - rsa_add_verify_data, - rsa_verify, + &crypto_algos[0], &checksum_algos[0], }, { "sha256,rsa2048", - rsa_sign, - rsa_add_verify_data, - rsa_verify, + &crypto_algos[0], &checksum_algos[1], }, { "sha256,rsa4096", - rsa_sign, - rsa_add_verify_data, - rsa_verify, - &checksum_algos[2], + &crypto_algos[1], + &checksum_algos[1], } }; @@ -197,7 +196,8 @@ int fit_image_check_sig(const void *fit, int noffset, const void *data, region.data = data; region.size = size; - if (info.algo->verify(&info, ®ion, 1, fit_value, fit_value_len)) { + if (info.algo->crypto->verify(&info, ®ion, 1, fit_value, + fit_value_len)) { *err_msgp = "Verification failed"; return -1; } @@ -378,8 +378,8 @@ int fit_config_check_sig(const void *fit, int noffset, int required_keynode, struct image_region region[count]; fit_region_make_list(fit, fdt_regions, count, region); - if (info.algo->verify(&info, region, count, fit_value, - fit_value_len)) { + if (info.algo->crypto->verify(&info, region, count, fit_value, + fit_value_len)) { *err_msgp = "Verification failed"; return -1; } diff --git a/include/image.h b/include/image.h index de73a07..c3c9866 100644 --- a/include/image.h +++ b/include/image.h @@ -1072,7 +1072,6 @@ struct checksum_algo { const int checksum_len; const int der_len; const uint8_t *der_prefix; - const int key_len; #if IMAGE_ENABLE_SIGN const EVP_MD *(*calculate_sign)(void); #endif @@ -1081,8 +1080,9 @@ struct checksum_algo { int region_count, uint8_t *checksum); }; -struct image_sig_algo { +struct crypto_algo { const char *name; /* Name of algorithm */ + const int key_len; /** * sign() - calculate and return signature for given input data @@ -1131,7 +1131,12 @@ struct image_sig_algo { int (*verify)(struct image_sign_info *info, const struct image_region region[], int region_count, uint8_t *sig, uint sig_len); +}; +struct image_sig_algo { + const char *name; + /* pointer to cryptosystem algorithm */ + struct crypto_algo *crypto; /* pointer to checksum algorithm */ struct checksum_algo *checksum; }; diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index ee8988d..61dc4c2 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -68,14 +68,14 @@ static int rsa_verify_padding(const uint8_t *msg, const int pad_len, * @sig: Signature * @sig_len: Number of bytes in signature * @hash: Pointer to the expected hash - * @algo: Checksum algo structure having information on RSA padding etc. + * @key_len: Number of bytes in rsa key + * @algo: Checksum algo structure having information on DER encoding etc. * @return 0 if verified, -ve on error */ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, const uint32_t sig_len, const uint8_t *hash, - struct checksum_algo *algo) + const uint32_t key_len, struct checksum_algo *algo) { - const uint8_t *padding; int pad_len; int ret; #if !defined(USE_HOSTCC) @@ -117,7 +117,7 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, return ret; } - pad_len = algo->key_len - algo->checksum_len; + pad_len = key_len - algo->checksum_len; /* Check pkcs1.5 padding bytes. */ ret = rsa_verify_padding(buf, pad_len, algo); @@ -183,7 +183,9 @@ static int rsa_verify_with_keynode(struct image_sign_info *info, return -EFAULT; } - ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum); + ret = rsa_verify_key(&prop, sig, sig_len, hash, + info->algo->crypto->key_len, + info->algo->checksum); return ret; } @@ -194,7 +196,7 @@ int rsa_verify(struct image_sign_info *info, { const void *blob = info->fdt_blob; /* Reserve memory for maximum checksum-length */ - uint8_t hash[info->algo->checksum->key_len]; + uint8_t hash[info->algo->crypto->key_len]; int ndepth, noffset; int sig_node, node; char name[100]; @@ -205,9 +207,10 @@ int rsa_verify(struct image_sign_info *info, * rsa-signature-length */ if (info->algo->checksum->checksum_len > - info->algo->checksum->key_len) { + info->algo->crypto->key_len) { debug("%s: invlaid checksum-algorithm %s for %s\n", - __func__, info->algo->checksum->name, info->algo->name); + __func__, info->algo->checksum->name, + info->algo->crypto->name); return -EINVAL; } diff --git a/tools/image-host.c b/tools/image-host.c index 1104695..dac85b4 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -213,7 +213,7 @@ static int fit_image_process_sig(const char *keydir, void *keydest, node_name = fit_get_name(fit, noffset, NULL); region.data = data; region.size = size; - ret = info.algo->sign(&info, ®ion, 1, &value, &value_len); + ret = info.algo->crypto->sign(&info, ®ion, 1, &value, &value_len); if (ret) { printf("Failed to sign '%s' signature node in '%s' image node: %d\n", node_name, image_name, ret); @@ -239,7 +239,7 @@ static int fit_image_process_sig(const char *keydir, void *keydest, info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); if (keydest) - ret = info.algo->add_verify_data(&info, keydest); + ret = info.algo->crypto->add_verify_data(&info, keydest); else return -1; @@ -588,7 +588,8 @@ static int fit_config_process_sig(const char *keydir, void *keydest, require_keys ? "conf" : NULL)) return -1; - ret = info.algo->sign(&info, region, region_count, &value, &value_len); + ret = info.algo->crypto->sign(&info, region, region_count, &value, + &value_len); free(region); if (ret) { printf("Failed to sign '%s' signature node in '%s' conf node\n", @@ -617,7 +618,7 @@ static int fit_config_process_sig(const char *keydir, void *keydest, /* Write the public key into the supplied FDT file */ if (keydest) { - ret = info.algo->add_verify_data(&info, keydest); + ret = info.algo->crypto->add_verify_data(&info, keydest); if (ret == -ENOSPC) return -ENOSPC; if (ret) {