u-boot/common/image-sig.c

137 lines
2.8 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2013, Google Inc.
*/
#include <common.h>
#include <log.h>
#include <malloc.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
#include <image.h>
#include <relocate.h>
#include <u-boot/ecdsa.h>
#include <u-boot/rsa.h>
#include <u-boot/hash-checksum.h>
#define IMAGE_MAX_HASHED_NODES 100
struct checksum_algo checksum_algos[] = {
{
.name = "sha1",
.checksum_len = SHA1_SUM_LEN,
.der_len = SHA1_DER_LEN,
.der_prefix = sha1_der_prefix,
.calculate = hash_calculate,
},
{
.name = "sha256",
.checksum_len = SHA256_SUM_LEN,
.der_len = SHA256_DER_LEN,
.der_prefix = sha256_der_prefix,
.calculate = hash_calculate,
},
#ifdef CONFIG_SHA384
{
.name = "sha384",
.checksum_len = SHA384_SUM_LEN,
.der_len = SHA384_DER_LEN,
.der_prefix = sha384_der_prefix,
.calculate = hash_calculate,
},
#endif
#ifdef CONFIG_SHA512
{
.name = "sha512",
.checksum_len = SHA512_SUM_LEN,
.der_len = SHA512_DER_LEN,
.der_prefix = sha512_der_prefix,
.calculate = hash_calculate,
},
#endif
};
struct checksum_algo *image_get_checksum_algo(const char *full_name)
{
int i;
const char *name;
if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
static bool done;
if (!done) {
done = true;
for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
struct checksum_algo *algo = &checksum_algos[i];
MANUAL_RELOC(algo->name);
MANUAL_RELOC(algo->calculate);
}
}
}
for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
name = checksum_algos[i].name;
/* Make sure names match and next char is a comma */
if (!strncmp(name, full_name, strlen(name)) &&
full_name[strlen(name)] == ',')
return &checksum_algos[i];
}
return NULL;
}
struct crypto_algo *image_get_crypto_algo(const char *full_name)
{
struct crypto_algo *crypto, *end;
const char *name;
if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
static bool done;
if (!done) {
done = true;
crypto = ll_entry_start(struct crypto_algo, cryptos);
end = ll_entry_end(struct crypto_algo, cryptos);
for (; crypto < end; crypto++) {
MANUAL_RELOC(crypto->name);
MANUAL_RELOC(crypto->verify);
}
}
}
/* Move name to after the comma */
name = strchr(full_name, ',');
if (!name)
return NULL;
name += 1;
crypto = ll_entry_start(struct crypto_algo, cryptos);
end = ll_entry_end(struct crypto_algo, cryptos);
for (; crypto < end; crypto++) {
if (!strcmp(crypto->name, name))
return crypto;
}
/* Not found */
return NULL;
}
struct padding_algo *image_get_padding_algo(const char *name)
{
image: rsa: Move padding_algos to linker lists We are not guaranteed to have the padding_pkcs_15_verify symbol since commit 92c960bc1d ("lib: rsa: Remove #ifdefs from rsa.h"), and commit 61416fe9df ("Kconfig: FIT_SIGNATURE should not select RSA_VERIFY") The padding_algos only make sense with RSA verification, which can now be disabled in lieu of ECDSA. In fact this will lead to build failures because of the missing symbol mentioned earlier. To resolve this, move the padding_algos to a linker list, with declarations moved to rsa_verify.c. This is consistent with commit 6909edb4ce ("image: rsa: Move verification algorithm to a linker list") One could argue that the added #ifdef USE_HOSTCC is ugly, and should be hidden within the U_BOOT_PADDING_ALGO() macro. However, this would be inconsistent with the "cryptos" list. This logic for was not previously explored: Without knowledge of the U_BOOT_PADDING_ALGO() macro, its use is similar to something being declared. However, should #ifndef USE_HOSTCC be part of the macro, it would not be obvious that it behaves differently on host code and target code. Having the #ifndef outside the macro makes this obvious. Also, the #ifdef is not always necessary. For example ecda-verify makes use of U_BOOT_CRYPTO_ALGO() without any accompanying #ifdefs. The fundamental issue is a lack of separation of host and target code in rsa_verify. Therefore, the declaration of a padding algo with the external #ifdef is more readable and consistent. Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2021-08-18 22:49:02 +00:00
struct padding_algo *padding, *end;
if (!name)
return NULL;
image: rsa: Move padding_algos to linker lists We are not guaranteed to have the padding_pkcs_15_verify symbol since commit 92c960bc1d ("lib: rsa: Remove #ifdefs from rsa.h"), and commit 61416fe9df ("Kconfig: FIT_SIGNATURE should not select RSA_VERIFY") The padding_algos only make sense with RSA verification, which can now be disabled in lieu of ECDSA. In fact this will lead to build failures because of the missing symbol mentioned earlier. To resolve this, move the padding_algos to a linker list, with declarations moved to rsa_verify.c. This is consistent with commit 6909edb4ce ("image: rsa: Move verification algorithm to a linker list") One could argue that the added #ifdef USE_HOSTCC is ugly, and should be hidden within the U_BOOT_PADDING_ALGO() macro. However, this would be inconsistent with the "cryptos" list. This logic for was not previously explored: Without knowledge of the U_BOOT_PADDING_ALGO() macro, its use is similar to something being declared. However, should #ifndef USE_HOSTCC be part of the macro, it would not be obvious that it behaves differently on host code and target code. Having the #ifndef outside the macro makes this obvious. Also, the #ifdef is not always necessary. For example ecda-verify makes use of U_BOOT_CRYPTO_ALGO() without any accompanying #ifdefs. The fundamental issue is a lack of separation of host and target code in rsa_verify. Therefore, the declaration of a padding algo with the external #ifdef is more readable and consistent. Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2021-08-18 22:49:02 +00:00
padding = ll_entry_start(struct padding_algo, paddings);
end = ll_entry_end(struct padding_algo, paddings);
for (; padding < end; padding++) {
if (!strcmp(padding->name, name))
return padding;
}
return NULL;
}