Commit d79ae6aa authored by Tom Rini's avatar Tom Rini

Merge branch '2019-12-06-master-imports'

- Allow for the sysboot command, which is used to parse extlinux.conf
  files to be used without PXE support.  There is no functional change
  here aside from fixing distro boot in a few cases where we actually
  lacked the ability to parse the extlinux.conf file
- Add the x509/pkcs7 parsers from Linux, a pre-requisite to EFI Secure
  Boot support.
parents bead4f2f fb013eee
Pipeline #1577 canceled with stages
......@@ -88,6 +88,7 @@ config DISTRO_DEFAULTS
select CMD_PART if PARTITIONS
select CMD_PING if CMD_NET
select CMD_PXE if NET
select CMD_SYSBOOT
select ENV_VARS_UBOOT_CONFIG
select HUSH_PARSER
select SUPPORT_RAW_INITRD
......
......@@ -1889,6 +1889,7 @@ checkarmreloc: u-boot
fi
tools/version.h: include/version.h
$(Q)mkdir -p $(dir $@)
$(call if_changed,copy)
envtools: scripts_basic $(version_h) $(timestamp_h) tools/version.h
......@@ -1957,6 +1958,7 @@ clean: $(clean-dirs)
-o -name '*.ko.*' -o -name '*.su' -o -name '*.pyc' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \
-o -name '*.symtypes' -o -name 'modules.order' \
-o -name modules.builtin -o -name '.tmp_*.o.*' \
-o -name 'dsdt.aml' -o -name 'dsdt.asl.tmp' -o -name 'dsdt.c' \
......
......@@ -1625,6 +1625,7 @@ config CMD_LED
config CMD_DATE
bool "date"
default y if DM_RTC
select LIB_DATE
help
Enable the 'date' command for getting/setting the time/date in RTC
devices.
......@@ -1671,6 +1672,12 @@ config CMD_SOUND
sound init - set up sound system
sound play - play a sound
config CMD_SYSBOOT
bool "sysboot"
select MENU
help
Boot image via local extlinux.conf file
config CMD_QFW
bool "qfw"
select QFW
......
......@@ -111,7 +111,7 @@ ifdef CONFIG_PCI
obj-$(CONFIG_CMD_PCI) += pci.o
endif
obj-$(CONFIG_CMD_PINMUX) += pinmux.o
obj-$(CONFIG_CMD_PXE) += pxe.o
obj-$(CONFIG_CMD_PXE) += pxe.o pxe_utils.o
obj-$(CONFIG_CMD_WOL) += wol.o
obj-$(CONFIG_CMD_QFW) += qfw.o
obj-$(CONFIG_CMD_READ) += read.o
......@@ -130,6 +130,7 @@ obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
obj-$(CONFIG_CMD_SPI) += spi.o
obj-$(CONFIG_CMD_STRINGS) += strings.o
obj-$(CONFIG_CMD_SMC) += smccc.o
obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o pxe_utils.o
obj-$(CONFIG_CMD_TERMINAL) += terminal.o
obj-$(CONFIG_CMD_TIME) += time.o
obj-$(CONFIG_CMD_TRACE) += trace.o
......
......@@ -681,6 +681,23 @@ char *env_get(const char *name)
return NULL;
}
/*
* Like env_get, but prints an error if envvar isn't defined in the
* environment. It always returns what env_get does, so it can be used in
* place of env_get without changing error handling otherwise.
*/
char *from_env(const char *envvar)
{
char *ret;
ret = env_get(envvar);
if (!ret)
printf("missing environment variable: %s\n", envvar);
return ret;
}
/*
* Look up variable from environment for restricted C runtime env.
*/
......
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef __PXE_UTILS_H
#define __PXE_UTILS_H
/*
* A note on the pxe file parser.
*
* We're parsing files that use syslinux grammar, which has a few quirks.
* String literals must be recognized based on context - there is no
* quoting or escaping support. There's also nothing to explicitly indicate
* when a label section completes. We deal with that by ending a label
* section whenever we see a line that doesn't include.
*
* As with the syslinux family, this same file format could be reused in the
* future for non pxe purposes. The only action it takes during parsing that
* would throw this off is handling of include files. It assumes we're using
* pxe, and does a tftp download of a file listed as an include file in the
* middle of the parsing operation. That could be handled by refactoring it to
* take a 'include file getter' function.
*/
/*
* Describes a single label given in a pxe file.
*
* Create these with the 'label_create' function given below.
*
* name - the name of the menu as given on the 'menu label' line.
* kernel - the path to the kernel file to use for this label.
* append - kernel command line to use when booting this label
* initrd - path to the initrd to use for this label.
* attempted - 0 if we haven't tried to boot this label, 1 if we have.
* localboot - 1 if this label specified 'localboot', 0 otherwise.
* list - lets these form a list, which a pxe_menu struct will hold.
*/
struct pxe_label {
char num[4];
char *name;
char *menu;
char *kernel;
char *config;
char *append;
char *initrd;
char *fdt;
char *fdtdir;
int ipappend;
int attempted;
int localboot;
int localboot_val;
struct list_head list;
};
/*
* Describes a pxe menu as given via pxe files.
*
* title - the name of the menu as given by a 'menu title' line.
* default_label - the name of the default label, if any.
* bmp - the bmp file name which is displayed in background
* timeout - time in tenths of a second to wait for a user key-press before
* booting the default label.
* prompt - if 0, don't prompt for a choice unless the timeout period is
* interrupted. If 1, always prompt for a choice regardless of
* timeout.
* labels - a list of labels defined for the menu.
*/
struct pxe_menu {
char *title;
char *default_label;
char *bmp;
int timeout;
int prompt;
struct list_head labels;
};
extern bool is_pxe;
extern int (*do_getfile)(cmd_tbl_t *cmdtp, const char *file_path,
char *file_addr);
void destroy_pxe_menu(struct pxe_menu *cfg);
int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
unsigned long file_addr);
int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file,
unsigned long pxefile_addr_r);
void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg);
struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg);
int format_mac_pxe(char *outbuf, size_t outbuf_len);
#endif /* __PXE_UTILS_H */
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <command.h>
#include <env.h>
#include <fs.h>
#include "pxe_utils.h"
static char *fs_argv[5];
static int do_get_ext2(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_EXT2
fs_argv[0] = "ext2load";
fs_argv[3] = file_addr;
fs_argv[4] = (void *)file_path;
if (!do_ext2load(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
}
static int do_get_fat(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_FAT
fs_argv[0] = "fatload";
fs_argv[3] = file_addr;
fs_argv[4] = (void *)file_path;
if (!do_fat_fsload(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
}
static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_FS_GENERIC
fs_argv[0] = "load";
fs_argv[3] = file_addr;
fs_argv[4] = (void *)file_path;
if (!do_load(cmdtp, 0, 5, fs_argv, FS_TYPE_ANY))
return 1;
#endif
return -ENOENT;
}
/*
* Boots a system using a local disk syslinux/extlinux file
*
* Returns 0 on success, 1 on error.
*/
static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned long pxefile_addr_r;
struct pxe_menu *cfg;
char *pxefile_addr_str;
char *filename;
int prompt = 0;
is_pxe = false;
if (argc > 1 && strstr(argv[1], "-p")) {
prompt = 1;
argc--;
argv++;
}
if (argc < 4)
return cmd_usage(cmdtp);
if (argc < 5) {
pxefile_addr_str = from_env("pxefile_addr_r");
if (!pxefile_addr_str)
return 1;
} else {
pxefile_addr_str = argv[4];
}
if (argc < 6) {
filename = env_get("bootfile");
} else {
filename = argv[5];
env_set("bootfile", filename);
}
if (strstr(argv[3], "ext2")) {
do_getfile = do_get_ext2;
} else if (strstr(argv[3], "fat")) {
do_getfile = do_get_fat;
} else if (strstr(argv[3], "any")) {
do_getfile = do_get_any;
} else {
printf("Invalid filesystem: %s\n", argv[3]);
return 1;
}
fs_argv[1] = argv[1];
fs_argv[2] = argv[2];
if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
printf("Invalid pxefile address: %s\n", pxefile_addr_str);
return 1;
}
if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
printf("Error reading config file\n");
return 1;
}
cfg = parse_pxefile(cmdtp, pxefile_addr_r);
if (!cfg) {
printf("Error parsing config file\n");
return 1;
}
if (prompt)
cfg->prompt = 1;
handle_pxe_menu(cmdtp, cfg);
destroy_pxe_menu(cfg);
return 0;
}
U_BOOT_CMD(sysboot, 7, 1, do_sysboot,
"command to get and boot from syslinux files",
"[-p] <interface> <dev[:part]> <ext2|fat|any> [addr] [filename]\n"
" - load and parse syslinux menu file 'filename' from ext2, fat\n"
" or any filesystem on 'dev' on 'interface' to address 'addr'"
);
ASN1
====
Abstract Syntax Notation One (or ASN1) is a standard by ITU-T and ISO/IEC
and used as a description language for defining data structure in
an independent manner.
Any data described in ASN1 notation can be serialized (or encoded) and
de-serialized (or decoded) with well-defined encoding rules.
A combination of ASN1 compiler and ASN1 decoder library function will
provide a function interface for parsing encoded binary into specific
data structure:
1) define data structure in a text file (*.asn1)
2) define "action" routines for specific "tags" defined in (1)
3) generate bytecode as a C file (*.asn1.[ch]) from *.asn1 file
with ASN1 compiler (tools/asn1_compiler)
4) call a ASN1 decoder (asn1_ber_decoder()) with bytecode and data
Usage of ASN1 compiler
----------------------
asn1_compiler [-v] [-d] <grammar-file> <c-file> <hdr-file>
<grammar-file>: ASN1 input file
<c-file>: generated C file
<hdr-file>: generated include file
Usage of ASN1 decoder
---------------------
int asn1_ber_decoder(const struct asn1_decoder *decoder, void *context,
const unsigned char *data, size_t datalen);
@decoder: bytecode binary
@context: context for decoder
@data: data to be parsed
@datalen: size of data
As of writing this, ASN1 compiler and decoder are used to implement
X509 certificate parser, pcks7 message parser and RSA public key parser
for UEFI secure boot.
......@@ -7,6 +7,7 @@ menu "Real Time Clock"
config DM_RTC
bool "Enable Driver Model for RTC drivers"
depends on DM
select LIB_DATE
help
Enable drver model for real-time-clock drivers. The RTC uclass
then provides the rtc_get()/rtc_set() interface, delegating to
......
......@@ -7,7 +7,6 @@
obj-$(CONFIG_$(SPL_TPL_)DM_RTC) += rtc-uclass.o
obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o
obj-y += date.o
obj-y += rtc-lib.o
obj-$(CONFIG_RTC_DAVINCI) += davinci.o
obj-$(CONFIG_RTC_DS1302) += ds1302.o
......
......@@ -18,6 +18,7 @@
#include "ubifs.h"
#include <u-boot/zlib.h>
#include <linux/compat.h>
#include <linux/err.h>
#include <linux/lzo.h>
......@@ -70,24 +71,6 @@ struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
#ifdef __UBOOT__
/* from mm/util.c */
/**
* kmemdup - duplicate region of memory
*
* @src: memory region to duplicate
* @len: memory region length
* @gfp: GFP mask to use
*/
void *kmemdup(const void *src, size_t len, gfp_t gfp)
{
void *p;
p = kmalloc(len, gfp);
if (p)
memcpy(p, src, len);
return p;
}
struct crypto_comp {
int compressor;
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* RSA internal helpers
*
* Copyright (c) 2015, Intel Corporation
* Authors: Tadeusz Struk <tadeusz.struk@intel.com>
*/
#ifndef _RSA_HELPER_
#define _RSA_HELPER_
#include <linux/types.h>
/**
* rsa_key - RSA key structure
* @n : RSA modulus raw byte stream
* @e : RSA public exponent raw byte stream
* @d : RSA private exponent raw byte stream
* @p : RSA prime factor p of n raw byte stream
* @q : RSA prime factor q of n raw byte stream
* @dp : RSA exponent d mod (p - 1) raw byte stream
* @dq : RSA exponent d mod (q - 1) raw byte stream
* @qinv : RSA CRT coefficient q^(-1) mod p raw byte stream
* @n_sz : length in bytes of RSA modulus n
* @e_sz : length in bytes of RSA public exponent
* @d_sz : length in bytes of RSA private exponent
* @p_sz : length in bytes of p field
* @q_sz : length in bytes of q field
* @dp_sz : length in bytes of dp field
* @dq_sz : length in bytes of dq field
* @qinv_sz : length in bytes of qinv field
*/
struct rsa_key {
const u8 *n;
const u8 *e;
const u8 *d;
const u8 *p;
const u8 *q;
const u8 *dp;
const u8 *dq;
const u8 *qinv;
size_t n_sz;
size_t e_sz;
size_t d_sz;
size_t p_sz;
size_t q_sz;
size_t dp_sz;
size_t dq_sz;
size_t qinv_sz;
};
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len);
int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len);
extern struct crypto_template rsa_pkcs1pad_tmpl;
#endif
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* PKCS#7 crypto data parser
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _CRYPTO_PKCS7_H
#define _CRYPTO_PKCS7_H
#ifndef __UBOOT__
#include <linux/verification.h>
#include <crypto/public_key.h>
#endif
struct key;
struct pkcs7_message;
/*
* pkcs7_parser.c
*/
extern struct pkcs7_message *pkcs7_parse_message(const void *data,
size_t datalen);
extern void pkcs7_free_message(struct pkcs7_message *pkcs7);
extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
const void **_data, size_t *_datalen,
size_t *_headerlen);
#ifndef __UBOOT__
/*
* pkcs7_trust.c
*/
extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
struct key *trust_keyring);
/*
* pkcs7_verify.c
*/
extern int pkcs7_verify(struct pkcs7_message *pkcs7,
enum key_being_used_for usage);
extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
const void *data, size_t datalen);
#endif
#endif /* _CRYPTO_PKCS7_H */
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Asymmetric public-key algorithm definitions
*
* See Documentation/crypto/asymmetric-keys.txt
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _LINUX_PUBLIC_KEY_H
#define _LINUX_PUBLIC_KEY_H
#ifdef __UBOOT__
#include <linux/types.h>
#else
#include <linux/keyctl.h>
#endif
#include <linux/oid_registry.h>
/*
* Cryptographic data for the public-key subtype of the asymmetric key type.
*
* Note that this may include private part of the key as well as the public
* part.
*/
struct public_key {
void *key;
u32 keylen;
enum OID algo;
void *params;
u32 paramlen;
bool key_is_private;
const char *id_type;
const char *pkey_algo;
};
extern void public_key_free(struct public_key *key);
/*
* Public key cryptography signature data
*/
struct public_key_signature {
struct asymmetric_key_id *auth_ids[2];
u8 *s; /* Signature */
u32 s_size; /* Number of bytes in signature */
u8 *digest;
u8 digest_size; /* Number of bytes in digest */
const char *pkey_algo;
const char *hash_algo;
const char *encoding;
};
extern void public_key_signature_free(struct public_key_signature *sig);
#ifndef __UBOOT__
extern struct asymmetric_key_subtype public_key_subtype;
struct key;
struct key_type;
union key_payload;
extern int restrict_link_by_signature(struct key *dest_keyring,
const struct key_type *type,
const union key_payload *payload,
struct key *trust_keyring);
extern int restrict_link_by_key_or_keyring(struct key *dest_keyring,
const struct key_type *type,
const union key_payload *payload,
struct key *trusted);
extern int restrict_link_by_key_or_keyring_chain(struct key *trust_keyring,
const struct key_type *type,
const union key_payload *payload,
struct key *trusted);
extern int query_asymmetric_key(const struct kernel_pkey_params *,
struct kernel_pkey_query *);
extern int encrypt_blob(struct kernel_pkey_params *, const void *, void *);
extern int decrypt_blob(struct kernel_pkey_params *, const void *, void *);
extern int create_signature(struct kernel_pkey_params *, const void *, void *);
extern int verify_signature(const struct key *,
const struct public_key_signature *);
int public_key_verify_signature(const struct public_key *pkey,
const struct public_key_signature *sig);
#endif /* !__UBOOT__ */
#endif /* _LINUX_PUBLIC_KEY_H */
......@@ -113,6 +113,16 @@ int env_match(unsigned char *name, int index);
*/
char *env_get(const char *varname);
/*
* Like env_get, but prints an error if envvar isn't defined in the
* environment. It always returns what env_get does, so it can be used in
* place of env_get without changing error handling otherwise.
*
* @varname: Variable to look up
* @return value of variable, or NULL if not found
*/
char *from_env(const char *envvar);
/**
* env_get_f() - Look up the value of an environment variable (early)
*
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Asymmetric Public-key cryptography key type interface
*
* See Documentation/crypto/asymmetric-keys.txt
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _KEYS_ASYMMETRIC_TYPE_H
#define _KEYS_ASYMMETRIC_TYPE_H
#ifndef __UBOOT__
#include <linux/key-type.h>
#include <linux/verification.h>
extern struct key_type key_type_asymmetric;
/*
* The key payload is four words. The asymmetric-type key uses them as
* follows:
*/
enum asymmetric_payload_bits {
asym_crypto, /* The data representing the key */
asym_subtype, /* Pointer to an asymmetric_key_subtype struct */
asym_key_ids, /* Pointer to an asymmetric_key_ids struct */
asym_auth /* The key's authorisation (signature, parent key ID) */
};
#endif /* !__UBOOT__ */
/*
* Identifiers for an asymmetric key ID. We have three ways of looking up a
* key derived from an X.509 certificate:
*
* (1) Serial Number & Issuer. Non-optional. This is the only valid way to
* map a PKCS#7 signature to an X.509 certificate.
*
* (2) Issuer & Subject Unique IDs. Optional. These were the original way to
* match X.509 certificates, but have fallen into disuse in favour of (3).
*
* (3) Auth & Subject Key Identifiers. Optional. SKIDs are only provided on
* CA keys that are intended to sign other keys, so don't appear in end
* user certificates unless forced.
*
* We could also support an PGP key identifier, which is just a SHA1 sum of the
* public key and certain parameters, but since we don't support PGP keys at
* the moment, we shall ignore those.
*
* What we actually do is provide a place where binary identifiers can be
* stashed and then compare against them when checking for an id match.
*/
struct asymmetric_key_id {
unsigned short len;
unsigned char data[];
};
struct asymmetric_key_ids {
void *id[2];
};
extern bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
const struct asymmetric_key_id *kid2);
extern bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
const struct asymmetric_key_id *kid2);
extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
size_t len_1,
const void *val_2,
size_t len_2);
#ifndef __UBOOT__
static inline
const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
{
return key->payload.data[asym_key_ids];
}
extern struct key *find_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id_0,
const struct asymmetric_key_id *id_1,
bool partial);
#endif
/*
* The payload is at the discretion of the subtype.
*/
#endif /* _KEYS_ASYMMETRIC_TYPE_H */
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* ASN.1 BER/DER/CER encoding definitions
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _LINUX_ASN1_H
#define _LINUX_ASN1_H
/* Class */
enum asn1_class {
ASN1_UNIV = 0, /* Universal */
ASN1_APPL = 1, /* Application */