summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2024-10-14 13:34:06 -0600
committerTom Rini <[email protected]>2024-10-14 17:59:04 -0600
commitd467f359c4c875a96857ced2b660b4d185b4714f (patch)
treed49653e08ea21126541f520a7e61478575fcf0d8 /include
parentc7aafb20ce9937f1e178ded46d8f22742f54c982 (diff)
parente65dcfe6bb7b5a24e68b132f5a2da82cf088017a (diff)
Merge patch series "Integrate MbedTLS v3.6 LTS with U-Boot"
Raymond Mao <[email protected]> says: Integrate MbedTLS v3.6 LTS (currently v3.6.0) with U-Boot. Motivations: ------------ 1. MbedTLS is well maintained with LTS versions. 2. LWIP is integrated with MbedTLS and easily to enable HTTPS. 3. MbedTLS recently switched license back to GPLv2. Prerequisite: ------------- This patch series requires mbedtls git repo to be added as a subtree to the main U-Boot repo via: $ git subtree add --prefix lib/mbedtls/external/mbedtls \ https://github.com/Mbed-TLS/mbedtls.git \ v3.6.0 --squash Moreover, due to the Windows-style files from mbedtls git repo, we need to convert the CRLF endings to LF and do a commit manually: $ git add --renormalize . $ git commit New Kconfig options: -------------------- `MBEDTLS_LIB` is for MbedTLS general switch. `MBEDTLS_LIB_CRYPTO` is for replacing original digest and crypto libs with MbedTLS. `MBEDTLS_LIB_CRYPTO_ALT` is for using original U-Boot crypto libs as MbedTLS crypto alternatives. `MBEDTLS_LIB_X509` is for replacing original X509, PKCS7, MSCode, ASN1, and Pubkey parser with MbedTLS. By default `MBEDTLS_LIB_CRYPTO_ALT` and `MBEDTLS_LIB_X509` are selected when `MBEDTLS_LIB` is enabled. `LEGACY_CRYPTO` is introduced as a main switch for legacy crypto library. `LEGACY_CRYPTO_BASIC` is for the basic crypto functionalities and `LEGACY_CRYPTO_CERT` is for the certificate related functionalities. For each of the algorithm, a pair of `<alg>_LEGACY` and `<alg>_MBEDTLS` Kconfig options are introduced. Meanwhile, `SPL_` Kconfig options are introduced. In this patch set, MBEDTLS_LIB, MBEDTLS_LIB_CRYPTO and MBEDTLS_LIB_X509 are by default enabled in qemu_arm64_defconfig and sandbox_defconfig for testing purpose. Patches for external MbedTLS project: ------------------------------------- Since U-Boot uses Microsoft Authentication Code to verify PE/COFFs executables which is not supported by MbedTLS at the moment, addtional patches for MbedTLS are created to adapt with the EFI loader: 1. Decoding of Microsoft Authentication Code. 2. Decoding of PKCS#9 Authenticate Attributes. 3. Extending MbedTLS PKCS#7 lib to support multiple signer's certificates. 4. MbedTLS native test suites for PKCS#7 signer's info. All above 4 patches (tagged with `mbedtls/external`) are submitted to MbedTLS project and being reviewed, eventually they should be part of MbedTLS LTS release. But before that, please merge them into U-Boot, otherwise the building will be broken when MBEDTLS_LIB_X509 is enabled. See below PR link for the reference: https://github.com/Mbed-TLS/mbedtls/pull/9001 Miscellaneous: -------------- Optimized MbedTLS library size by tailoring the config file and disabling all unnecessary features for EFI loader. From v2, original libs (rsa, asn1_decoder, rsa_helper, md5, sha1, sha256, sha512) are completely replaced when MbedTLS is enabled. From v3, the size-growth is slightly reduced by refactoring Hash functions. From v6, smaller implementations for SHA256 and SHA512 are enabled and target size reduce significantly. Target(QEMU arm64) size-growth when enabling MbedTLS: v1: 6.03% v2: 4.66% v3 - v5: 4.55% v6: 2.90% Tests done: ----------- EFI Secure Boot test (EFI variables loading and verifying, EFI signed image verifying and booting) via U-Boot console. EFI Secure Boot and Capsule sandbox test passed. Known issues: ------------- None. Link: https://lore.kernel.org/u-boot/[email protected]/
Diffstat (limited to 'include')
-rw-r--r--include/crypto/mscode.h4
-rw-r--r--include/crypto/pkcs7_parser.h56
-rw-r--r--include/crypto/public_key.h6
-rw-r--r--include/crypto/x509_parser.h55
-rw-r--r--include/limits.h25
-rw-r--r--include/linux/kernel.h13
-rw-r--r--include/stdlib.h1
-rw-r--r--include/u-boot/md5.h14
-rw-r--r--include/u-boot/sha1.h37
-rw-r--r--include/u-boot/sha256.h20
-rw-r--r--include/u-boot/sha512.h9
11 files changed, 211 insertions, 29 deletions
diff --git a/include/crypto/mscode.h b/include/crypto/mscode.h
index 551058b96e6..678e69001b9 100644
--- a/include/crypto/mscode.h
+++ b/include/crypto/mscode.h
@@ -9,6 +9,10 @@
#ifndef __UBOOT__
#include <crypto/hash_info.h>
#endif
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+#include <mbedtls/asn1.h>
+#include <mbedtls/oid.h>
+#endif
struct pefile_context {
#ifndef __UBOOT__
diff --git a/include/crypto/pkcs7_parser.h b/include/crypto/pkcs7_parser.h
index 2c45cce5234..469c2711fa6 100644
--- a/include/crypto/pkcs7_parser.h
+++ b/include/crypto/pkcs7_parser.h
@@ -11,6 +11,12 @@
#include <linux/oid_registry.h>
#include <crypto/pkcs7.h>
#include <crypto/x509_parser.h>
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+#include <mbedtls/pkcs7.h>
+#include <library/x509_internal.h>
+#include <mbedtls/asn1.h>
+#include <mbedtls/oid.h>
+#endif
#include <linux/printk.h>
#define kenter(FMT, ...) \
@@ -18,7 +24,54 @@
#define kleave(FMT, ...) \
pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__)
+/* Backup the parsed MedTLS context that we need */
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+struct pkcs7_mbedtls_ctx {
+ void *content_data;
+};
+
+struct pkcs7_sinfo_mbedtls_ctx {
+ void *authattrs_data;
+ void *content_data_digest;
+};
+#endif
+
+/*
+ * MbedTLS integration Notes:
+ *
+ * MbedTLS PKCS#7 library does not originally support parsing MicroSoft
+ * Authentication Code which is used for verifying the PE image digest.
+ *
+ * 1. Authenticated Attributes (authenticatedAttributes)
+ * MbedTLS assumes unauthenticatedAttributes and authenticatedAttributes
+ * fields not exist.
+ * See MbedTLS function 'pkcs7_get_signer_info' for details.
+ *
+ * 2. MicroSoft Authentication Code (mscode)
+ * MbedTLS only supports Content Data type defined as 1.2.840.113549.1.7.1
+ * (MBEDTLS_OID_PKCS7_DATA, aka OID_data).
+ * 1.3.6.1.4.1.311.2.1.4 (MicroSoft Authentication Code, aka
+ * OID_msIndirectData) is not supported.
+ * See MbedTLS function 'pkcs7_get_content_info_type' for details.
+ *
+ * But the EFI loader assumes that a PKCS#7 message with an EFI image always
+ * contains MicroSoft Authentication Code as Content Data (msg->data is NOT
+ * NULL), see function 'efi_signature_verify'.
+ *
+ * MbedTLS patch "0002-support-MicroSoft-authentication-code-in-PKCS7-lib.patch"
+ * is to support both above features by parsing the Content Data and
+ * Authenticate Attributes from a given PKCS#7 message.
+ *
+ * Other fields we don't need to populate from MbedTLS, which are used
+ * internally by pkcs7_verify:
+ * 'signer', 'unsupported_crypto', 'blacklisted'
+ * 'sig->digest' is used internally by pkcs7_digest to calculate the hash of
+ * Content Data or Authenticate Attributes.
+ */
struct pkcs7_signed_info {
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+ struct pkcs7_sinfo_mbedtls_ctx *mbedtls_ctx;
+#endif
struct pkcs7_signed_info *next;
struct x509_certificate *signer; /* Signing certificate (in msg->certs) */
unsigned index;
@@ -55,6 +108,9 @@ struct pkcs7_signed_info {
};
struct pkcs7_message {
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+ struct pkcs7_mbedtls_ctx *mbedtls_ctx;
+#endif
struct x509_certificate *certs; /* Certificate list */
struct x509_certificate *crl; /* Revocation list */
struct pkcs7_signed_info *signed_infos;
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 3ba90fcc348..25cfb68adce 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -12,6 +12,12 @@
#ifdef __UBOOT__
#include <linux/types.h>
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+#include <library/common.h>
+#include <mbedtls/pk.h>
+#include <mbedtls/x509_crt.h>
+#include <mbedtls/md.h>
+#endif
#else
#include <linux/keyctl.h>
#endif
diff --git a/include/crypto/x509_parser.h b/include/crypto/x509_parser.h
index 4cbdc1d6612..0e22e33f66b 100644
--- a/include/crypto/x509_parser.h
+++ b/include/crypto/x509_parser.h
@@ -11,8 +11,35 @@
#include <linux/time.h>
#include <crypto/public_key.h>
#include <keys/asymmetric-type.h>
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+#include <image.h>
+#include <mbedtls/error.h>
+#include <mbedtls/asn1.h>
+#endif
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+struct x509_cert_mbedtls_ctx {
+ void *tbs; /* Signed data */
+ void *raw_serial; /* Raw serial number in ASN.1 */
+ void *raw_issuer; /* Raw issuer name in ASN.1 */
+ void *raw_subject; /* Raw subject name in ASN.1 */
+ void *raw_skid; /* Raw subjectKeyId in ASN.1 */
+};
+#endif
+
+/*
+ * MbedTLS integration Notes:
+ *
+ * Fields we don't need to populate from MbedTLS context:
+ * 'raw_sig' and 'raw_sig_size' are buffer for x509_parse_context,
+ * not needed for MbedTLS.
+ * 'signer' and 'seen' are used internally by pkcs7_verify.
+ * 'verified' is not in use.
+ */
struct x509_certificate {
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+ struct x509_cert_mbedtls_ctx *mbedtls_ctx;
+#endif
struct x509_certificate *next;
struct x509_certificate *signer; /* Certificate that signed this one */
struct public_key *pub; /* Public key details */
@@ -48,6 +75,32 @@ struct x509_certificate {
* x509_cert_parser.c
*/
extern void x509_free_certificate(struct x509_certificate *cert);
+#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+/**
+ * x509_populate_pubkey() - Populate public key from MbedTLS context
+ *
+ * @cert: Pointer to MbedTLS X509 cert
+ * @pub_key: Pointer to the populated public key handle
+ * Return: 0 on succcess, error code on failure
+ */
+int x509_populate_pubkey(mbedtls_x509_crt *cert, struct public_key **pub_key);
+/**
+ * x509_populate_cert() - Populate X509 cert from MbedTLS context
+ *
+ * @mbedtls_cert: Pointer to MbedTLS X509 cert
+ * @pcert: Pointer to the populated X509 cert handle
+ * Return: 0 on succcess, error code on failure
+ */
+int x509_populate_cert(mbedtls_x509_crt *mbedtls_cert,
+ struct x509_certificate **pcert);
+/**
+ * x509_get_timestamp() - Translate timestamp from MbedTLS context
+ *
+ * @x509_time: Pointer to MbedTLS time
+ * Return: Time in time64_t format
+ */
+time64_t x509_get_timestamp(const mbedtls_x509_time *x509_time);
+#endif
extern struct x509_certificate *x509_cert_parse(const void *data, size_t datalen);
extern int x509_decode_time(time64_t *_t, size_t hdrlen,
unsigned char tag,
@@ -56,6 +109,8 @@ extern int x509_decode_time(time64_t *_t, size_t hdrlen,
/*
* x509_public_key.c
*/
+#if !CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
extern int x509_get_sig_params(struct x509_certificate *cert);
+#endif
extern int x509_check_for_self_signed(struct x509_certificate *cert);
#endif /* _X509_PARSER_H */
diff --git a/include/limits.h b/include/limits.h
new file mode 100644
index 00000000000..4700cc7a59f
--- /dev/null
+++ b/include/limits.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _LIMITS_H
+#define _LIMITS_H
+
+#define INT_MAX 0x7fffffff
+#define UINT_MAX 0xffffffffU
+#define CHAR_BIT 8
+#define UINT32_MAX 0xffffffffU
+#define UINT64_MAX 0xffffffffffffffffULL
+
+#ifdef CONFIG_64BIT
+ #define UINTPTR_MAX UINT64_MAX
+#else
+ #define UINTPTR_MAX UINT32_MAX
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX UINTPTR_MAX
+#endif
+#ifndef SSIZE_MAX
+#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
+#endif
+
+#endif /* _LIMITS_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 939465f372b..9467edd65ab 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -3,25 +3,18 @@
#include <linux/types.h>
#include <linux/printk.h> /* for printf/pr_* utilities */
+#include <limits.h>
#define USHRT_MAX ((u16)(~0U))
#define SHRT_MAX ((s16)(USHRT_MAX>>1))
#define SHRT_MIN ((s16)(-SHRT_MAX - 1))
-#define INT_MAX ((int)(~0U>>1))
#define INT_MIN (-INT_MAX - 1)
-#define UINT_MAX (~0U)
#define LONG_MAX ((long)(~0UL>>1))
#define LONG_MIN (-LONG_MAX - 1)
#define ULONG_MAX (~0UL)
#define LLONG_MAX ((long long)(~0ULL>>1))
#define LLONG_MIN (-LLONG_MAX - 1)
#define ULLONG_MAX (~0ULL)
-#ifndef SIZE_MAX
-#define SIZE_MAX (~(size_t)0)
-#endif
-#ifndef SSIZE_MAX
-#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
-#endif
#define U8_MAX ((u8)~0U)
#define S8_MAX ((s8)(U8_MAX>>1))
@@ -36,10 +29,6 @@
#define S64_MAX ((s64)(U64_MAX>>1))
#define S64_MIN ((s64)(-S64_MAX - 1))
-/* Aliases defined by stdint.h */
-#define UINT32_MAX U32_MAX
-#define UINT64_MAX U64_MAX
-
#define INT32_MAX S32_MAX
#define STACK_MAGIC 0xdeadbeef
diff --git a/include/stdlib.h b/include/stdlib.h
index 9c175d4d74c..dedfd52a144 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -7,5 +7,6 @@
#define __STDLIB_H_
#include <malloc.h>
+#include <rand.h>
#endif /* __STDLIB_H_ */
diff --git a/include/u-boot/md5.h b/include/u-boot/md5.h
index c465925ea8d..c98b1a58088 100644
--- a/include/u-boot/md5.h
+++ b/include/u-boot/md5.h
@@ -6,10 +6,17 @@
#ifndef _MD5_H
#define _MD5_H
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+#include <mbedtls/md5.h>
+#endif
#include "compiler.h"
#define MD5_SUM_LEN 16
+#define MD5_DEF_CHUNK_SZ 0x10000
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+typedef mbedtls_md5_context MD5Context;
+#else
typedef struct MD5Context {
__u32 buf[4];
__u32 bits[2];
@@ -18,18 +25,13 @@ typedef struct MD5Context {
__u32 in32[16];
};
} MD5Context;
+#endif
void MD5Init(MD5Context *ctx);
void MD5Update(MD5Context *ctx, unsigned char const *buf, unsigned int len);
void MD5Final(unsigned char digest[16], MD5Context *ctx);
/*
- * Calculate and store in 'output' the MD5 digest of 'len' bytes at
- * 'input'. 'output' must have enough space to hold 16 bytes.
- */
-void md5 (unsigned char *input, int len, unsigned char output[16]);
-
-/*
* Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'.
* 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the
* watchdog every 'chunk_sz' bytes of input processed.
diff --git a/include/u-boot/sha1.h b/include/u-boot/sha1.h
index c1e9f67068d..2fca7f1be16 100644
--- a/include/u-boot/sha1.h
+++ b/include/u-boot/sha1.h
@@ -16,6 +16,21 @@
#include <linux/types.h>
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+/*
+ * FIXME:
+ * MbedTLS define the members of "mbedtls_sha256_context" as private,
+ * but "state" needs to be access by arch/arm/cpu/armv8/sha1_ce_glue.
+ * MBEDTLS_ALLOW_PRIVATE_ACCESS needs to be enabled to allow the external
+ * access.
+ * Directly including <external/mbedtls/library/common.h> is not allowed,
+ * since this will include <malloc.h> and break the sandbox test.
+ */
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#include <mbedtls/sha1.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -24,8 +39,17 @@ extern "C" {
#define SHA1_SUM_LEN 20
#define SHA1_DER_LEN 15
+#define SHA1_DEF_CHUNK_SZ 0x10000
+
+#define K_IPAD_VAL 0x36
+#define K_OPAD_VAL 0x5C
+#define K_PAD_LEN 64
+
extern const uint8_t sha1_der_prefix[];
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+typedef mbedtls_sha1_context sha1_context;
+#else
/**
* \brief SHA-1 context structure
*/
@@ -36,13 +60,14 @@ typedef struct
unsigned char buffer[64]; /*!< data block being processed */
}
sha1_context;
+#endif
/**
* \brief SHA-1 context setup
*
* \param ctx SHA-1 context to be initialized
*/
-void sha1_starts( sha1_context *ctx );
+void sha1_starts(sha1_context *ctx);
/**
* \brief SHA-1 process buffer
@@ -63,16 +88,6 @@ void sha1_update(sha1_context *ctx, const unsigned char *input,
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
/**
- * \brief Output = SHA-1( input buffer )
- *
- * \param input buffer holding the data
- * \param ilen length of the input data
- * \param output SHA-1 checksum result
- */
-void sha1_csum(const unsigned char *input, unsigned int ilen,
- unsigned char *output);
-
-/**
* \brief Output = SHA-1( input buffer ), with watchdog triggering
*
* \param input buffer holding the data
diff --git a/include/u-boot/sha256.h b/include/u-boot/sha256.h
index a4fe176c0b4..b58d5b58d39 100644
--- a/include/u-boot/sha256.h
+++ b/include/u-boot/sha256.h
@@ -3,6 +3,22 @@
#include <linux/types.h>
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+/*
+ * FIXME:
+ * MbedTLS define the members of "mbedtls_sha256_context" as private,
+ * but "state" needs to be access by arch/arm/cpu/armv8/sha256_ce_glue.
+ * MBEDTLS_ALLOW_PRIVATE_ACCESS needs to be enabled to allow the external
+ * access.
+ * Directly including <external/mbedtls/library/common.h> is not allowed,
+ * since this will include <malloc.h> and break the sandbox test.
+ */
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#include <mbedtls/sha256.h>
+#endif
+
+#define SHA224_SUM_LEN 28
#define SHA256_SUM_LEN 32
#define SHA256_DER_LEN 19
@@ -11,11 +27,15 @@ extern const uint8_t sha256_der_prefix[];
/* Reset watchdog each time we process this many bytes */
#define CHUNKSZ_SHA256 (64 * 1024)
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+typedef mbedtls_sha256_context sha256_context;
+#else
typedef struct {
uint32_t total[2];
uint32_t state[8];
uint8_t buffer[64];
} sha256_context;
+#endif
void sha256_starts(sha256_context * ctx);
void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length);
diff --git a/include/u-boot/sha512.h b/include/u-boot/sha512.h
index 83c2119cd26..7e10f590a1d 100644
--- a/include/u-boot/sha512.h
+++ b/include/u-boot/sha512.h
@@ -3,6 +3,10 @@
#include <linux/types.h>
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+#include <mbedtls/sha512.h>
+#endif
+
#define SHA384_SUM_LEN 48
#define SHA384_DER_LEN 19
#define SHA512_SUM_LEN 64
@@ -12,11 +16,16 @@
#define CHUNKSZ_SHA384 (16 * 1024)
#define CHUNKSZ_SHA512 (16 * 1024)
+#if defined(CONFIG_MBEDTLS_LIB_CRYPTO)
+typedef mbedtls_sha512_context sha384_context;
+typedef mbedtls_sha512_context sha512_context;
+#else
typedef struct {
uint64_t state[SHA512_SUM_LEN / 8];
uint64_t count[2];
uint8_t buf[SHA512_BLOCK_SIZE];
} sha512_context;
+#endif
extern const uint8_t sha512_der_prefix[];