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 <aduda@meraki.com>
Signed-off-by: aduda <aduda@meraki.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Andrew Duda 2016-11-08 18:53:41 +00:00 committed by Tom Rini
parent da29f2991d
commit 0c1d74fda7
4 changed files with 48 additions and 39 deletions

View file

@ -36,7 +36,6 @@ struct checksum_algo checksum_algos[] = {
SHA1_SUM_LEN, SHA1_SUM_LEN,
SHA1_DER_LEN, SHA1_DER_LEN,
sha1_der_prefix, sha1_der_prefix,
RSA2048_BYTES,
#if IMAGE_ENABLE_SIGN #if IMAGE_ENABLE_SIGN
EVP_sha1, EVP_sha1,
#endif #endif
@ -47,18 +46,6 @@ struct checksum_algo checksum_algos[] = {
SHA256_SUM_LEN, SHA256_SUM_LEN,
SHA256_DER_LEN, SHA256_DER_LEN,
sha256_der_prefix, sha256_der_prefix,
RSA2048_BYTES,
#if IMAGE_ENABLE_SIGN
EVP_sha256,
#endif
hash_calculate,
},
{
"sha256",
SHA256_SUM_LEN,
SHA256_DER_LEN,
sha256_der_prefix,
RSA4096_BYTES,
#if IMAGE_ENABLE_SIGN #if IMAGE_ENABLE_SIGN
EVP_sha256, EVP_sha256,
#endif #endif
@ -67,27 +54,39 @@ struct checksum_algo checksum_algos[] = {
}; };
struct image_sig_algo image_sig_algos[] = { struct crypto_algo crypto_algos[] = {
{ {
"sha1,rsa2048", "rsa2048",
RSA2048_BYTES,
rsa_sign, rsa_sign,
rsa_add_verify_data, rsa_add_verify_data,
rsa_verify, rsa_verify,
},
{
"rsa4096",
RSA4096_BYTES,
rsa_sign,
rsa_add_verify_data,
rsa_verify,
}
};
struct image_sig_algo image_sig_algos[] = {
{
"sha1,rsa2048",
&crypto_algos[0],
&checksum_algos[0], &checksum_algos[0],
}, },
{ {
"sha256,rsa2048", "sha256,rsa2048",
rsa_sign, &crypto_algos[0],
rsa_add_verify_data,
rsa_verify,
&checksum_algos[1], &checksum_algos[1],
}, },
{ {
"sha256,rsa4096", "sha256,rsa4096",
rsa_sign, &crypto_algos[1],
rsa_add_verify_data, &checksum_algos[1],
rsa_verify,
&checksum_algos[2],
} }
}; };
@ -197,7 +196,8 @@ int fit_image_check_sig(const void *fit, int noffset, const void *data,
region.data = data; region.data = data;
region.size = size; region.size = size;
if (info.algo->verify(&info, &region, 1, fit_value, fit_value_len)) { if (info.algo->crypto->verify(&info, &region, 1, fit_value,
fit_value_len)) {
*err_msgp = "Verification failed"; *err_msgp = "Verification failed";
return -1; return -1;
} }
@ -378,8 +378,8 @@ int fit_config_check_sig(const void *fit, int noffset, int required_keynode,
struct image_region region[count]; struct image_region region[count];
fit_region_make_list(fit, fdt_regions, count, region); fit_region_make_list(fit, fdt_regions, count, region);
if (info.algo->verify(&info, region, count, fit_value, if (info.algo->crypto->verify(&info, region, count, fit_value,
fit_value_len)) { fit_value_len)) {
*err_msgp = "Verification failed"; *err_msgp = "Verification failed";
return -1; return -1;
} }

View file

@ -1072,7 +1072,6 @@ struct checksum_algo {
const int checksum_len; const int checksum_len;
const int der_len; const int der_len;
const uint8_t *der_prefix; const uint8_t *der_prefix;
const int key_len;
#if IMAGE_ENABLE_SIGN #if IMAGE_ENABLE_SIGN
const EVP_MD *(*calculate_sign)(void); const EVP_MD *(*calculate_sign)(void);
#endif #endif
@ -1081,8 +1080,9 @@ struct checksum_algo {
int region_count, uint8_t *checksum); int region_count, uint8_t *checksum);
}; };
struct image_sig_algo { struct crypto_algo {
const char *name; /* Name of algorithm */ const char *name; /* Name of algorithm */
const int key_len;
/** /**
* sign() - calculate and return signature for given input data * sign() - calculate and return signature for given input data
@ -1131,7 +1131,12 @@ struct image_sig_algo {
int (*verify)(struct image_sign_info *info, int (*verify)(struct image_sign_info *info,
const struct image_region region[], int region_count, const struct image_region region[], int region_count,
uint8_t *sig, uint sig_len); 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 */ /* pointer to checksum algorithm */
struct checksum_algo *checksum; struct checksum_algo *checksum;
}; };

View file

@ -68,14 +68,14 @@ static int rsa_verify_padding(const uint8_t *msg, const int pad_len,
* @sig: Signature * @sig: Signature
* @sig_len: Number of bytes in signature * @sig_len: Number of bytes in signature
* @hash: Pointer to the expected hash * @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 * @return 0 if verified, -ve on error
*/ */
static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
const uint32_t sig_len, const uint8_t *hash, 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 pad_len;
int ret; int ret;
#if !defined(USE_HOSTCC) #if !defined(USE_HOSTCC)
@ -117,7 +117,7 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
return ret; return ret;
} }
pad_len = algo->key_len - algo->checksum_len; pad_len = key_len - algo->checksum_len;
/* Check pkcs1.5 padding bytes. */ /* Check pkcs1.5 padding bytes. */
ret = rsa_verify_padding(buf, pad_len, algo); 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; 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; return ret;
} }
@ -194,7 +196,7 @@ int rsa_verify(struct image_sign_info *info,
{ {
const void *blob = info->fdt_blob; const void *blob = info->fdt_blob;
/* Reserve memory for maximum checksum-length */ /* 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 ndepth, noffset;
int sig_node, node; int sig_node, node;
char name[100]; char name[100];
@ -205,9 +207,10 @@ int rsa_verify(struct image_sign_info *info,
* rsa-signature-length * rsa-signature-length
*/ */
if (info->algo->checksum->checksum_len > 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", 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; return -EINVAL;
} }

View file

@ -213,7 +213,7 @@ static int fit_image_process_sig(const char *keydir, void *keydest,
node_name = fit_get_name(fit, noffset, NULL); node_name = fit_get_name(fit, noffset, NULL);
region.data = data; region.data = data;
region.size = size; region.size = size;
ret = info.algo->sign(&info, &region, 1, &value, &value_len); ret = info.algo->crypto->sign(&info, &region, 1, &value, &value_len);
if (ret) { if (ret) {
printf("Failed to sign '%s' signature node in '%s' image node: %d\n", printf("Failed to sign '%s' signature node in '%s' image node: %d\n",
node_name, image_name, ret); 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); info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
if (keydest) if (keydest)
ret = info.algo->add_verify_data(&info, keydest); ret = info.algo->crypto->add_verify_data(&info, keydest);
else else
return -1; return -1;
@ -588,7 +588,8 @@ static int fit_config_process_sig(const char *keydir, void *keydest,
require_keys ? "conf" : NULL)) require_keys ? "conf" : NULL))
return -1; 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); free(region);
if (ret) { if (ret) {
printf("Failed to sign '%s' signature node in '%s' conf node\n", 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 */ /* Write the public key into the supplied FDT file */
if (keydest) { if (keydest) {
ret = info.algo->add_verify_data(&info, keydest); ret = info.algo->crypto->add_verify_data(&info, keydest);
if (ret == -ENOSPC) if (ret == -ENOSPC)
return -ENOSPC; return -ENOSPC;
if (ret) { if (ret) {