diff --git a/arch/arm/lib32/barebox.lds.S b/arch/arm/lib32/barebox.lds.S index 7230e5f..c479e02 100644 --- a/arch/arm/lib32/barebox.lds.S +++ b/arch/arm/lib32/barebox.lds.S @@ -55,7 +55,10 @@ BAREBOX_BARE_INIT_SIZE . = ALIGN(4); - .rodata : { *(.rodata*) } + .rodata : { + *(.rodata*) + RO_DATA_SECTION + } #ifdef CONFIG_ARM_UNWIND /* @@ -82,45 +85,6 @@ .barebox_imd : { BAREBOX_IMD } . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - __barebox_ratp_cmd_start = .; - .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - __usymtab_start = .; - __usymtab : { BAREBOX_SYMS } - __usymtab_end = .; - -#ifdef CONFIG_PCI - __start_pci_fixups_early = .; - .pci_fixup_early : { KEEP(*(.pci_fixup_early)) } - __end_pci_fixups_early = .; - __start_pci_fixups_header = .; - .pci_fixup_header : { KEEP(*(.pci_fixup_header)) } - __end_pci_fixups_header = .; - __start_pci_fixups_enable = .; - .pci_fixup_enable : { KEEP(*(.pci_fixup_enable)) } - __end_pci_fixups_enable = .; -#endif - - .oftables : { BAREBOX_CLK_TABLE() } - - .dtb : { BAREBOX_DTB() } .rel_dyn_start : { *(.__rel_dyn_start) } .rel.dyn : { *(.rel*) } diff --git a/arch/arm/lib64/barebox.lds.S b/arch/arm/lib64/barebox.lds.S index 694bbca..cf6ef18 100644 --- a/arch/arm/lib64/barebox.lds.S +++ b/arch/arm/lib64/barebox.lds.S @@ -53,7 +53,10 @@ BAREBOX_BARE_INIT_SIZE . = ALIGN(4); - .rodata : { *(.rodata*) } + .rodata : { + *(.rodata*) + RO_DATA_SECTION + } _etext = .; /* End of text and rodata section */ _sdata = .; @@ -63,47 +66,6 @@ .barebox_imd : { BAREBOX_IMD } - . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - __barebox_ratp_cmd_start = .; - .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - __usymtab_start = .; - __usymtab : { BAREBOX_SYMS } - __usymtab_end = .; - -#ifdef CONFIG_PCI - __start_pci_fixups_early = .; - .pci_fixup_early : { KEEP(*(.pci_fixup_early)) } - __end_pci_fixups_early = .; - __start_pci_fixups_header = .; - .pci_fixup_header : { KEEP(*(.pci_fixup_header)) } - __end_pci_fixups_header = .; - __start_pci_fixups_enable = .; - .pci_fixup_enable : { KEEP(*(.pci_fixup_enable)) } - __end_pci_fixups_enable = .; -#endif - - .oftables : { BAREBOX_CLK_TABLE() } - - .dtb : { BAREBOX_DTB() } - .rel_dyn_start : { *(.__rel_dyn_start) } .rela.dyn : { *(.rela*) } .rel_dyn_end : { *(.__rel_dyn_end) } diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S index 58b0c59..e96c3bf 100644 --- a/arch/mips/lib/barebox.lds.S +++ b/arch/mips/lib/barebox.lds.S @@ -30,7 +30,10 @@ PRE_IMAGE . = ALIGN(4); - .rodata : { *(.rodata*) } + .rodata : { + *(.rodata*) + RO_DATA_SECTION + } _etext = .; /* End of text and rodata section */ _sdata = .; @@ -40,46 +43,6 @@ .barebox_imd : { BAREBOX_IMD } - . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - __barebox_ratp_cmd_start = .; - .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - __usymtab_start = .; - __usymtab : { BAREBOX_SYMS } - __usymtab_end = .; - -#ifdef CONFIG_PCI - __start_pci_fixups_early = .; - .pci_fixup_early : { KEEP(*(.pci_fixup_early)) } - __end_pci_fixups_early = .; - __start_pci_fixups_header = .; - .pci_fixup_header : { KEEP(*(.pci_fixup_header)) } - __end_pci_fixups_header = .; - __start_pci_fixups_enable = .; - .pci_fixup_enable : { KEEP(*(.pci_fixup_enable)) } - __end_pci_fixups_enable = .; -#endif - .oftables : { BAREBOX_CLK_TABLE() } - - .dtb : { BAREBOX_DTB() } - _edata = .; .image_end : { *(.__image_end) } diff --git a/arch/nios2/cpu/barebox.lds.S b/arch/nios2/cpu/barebox.lds.S index fbcd1cd..8d82aa5 100644 --- a/arch/nios2/cpu/barebox.lds.S +++ b/arch/nios2/cpu/barebox.lds.S @@ -48,32 +48,11 @@ BAREBOX_BARE_INIT_SIZE . = ALIGN(4); - .rodata : { *(.rodata) } - . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - __barebox_ratp_cmd_start = .; - .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - ___usymtab_start = .; - __usymtab : { BAREBOX_SYMS } - ___usymtab_end = .; + .rodata : { + *(.rodata*) + RO_DATA_SECTION + } _etext = .; /* End of text and rodata section */ diff --git a/arch/openrisc/cpu/barebox.lds.S b/arch/openrisc/cpu/barebox.lds.S index c6807ae..adb0c22 100644 --- a/arch/openrisc/cpu/barebox.lds.S +++ b/arch/openrisc/cpu/barebox.lds.S @@ -49,36 +49,9 @@ *(.rodata); *(.rodata.*) *(.bbenv.rodata.*) + RO_DATA_SECTION } > ram - . = ALIGN(4); - . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } > ram - __barebox_cmd_end = .; - - __barebox_ratp_cmd_start = .; - .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } > ram - __barebox_ratp_cmd_end = .; - - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } > ram - __barebox_magicvar_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } > ram - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } > ram - __barebox_exitcalls_end = .; - - ___usymtab_start = .; - __usymtab : { BAREBOX_SYMS } > ram - ___usymtab_end = .; - - .dtb : { BAREBOX_DTB() } > ram - __etext = .; /* End of text and rodata section */ . = ALIGN(4); diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S index 3b8bf3c..6c91ed6 100644 --- a/arch/ppc/boards/pcm030/barebox.lds.S +++ b/arch/ppc/boards/pcm030/barebox.lds.S @@ -38,6 +38,7 @@ *(.rodata*) *(.rodata1*) *(.rodata.str1.4) + RO_DATA_SECTION } /* Read-only sections, merged into text segment: */ @@ -99,33 +100,6 @@ _edata = .; PROVIDE (edata = .); - . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - __barebox_ratp_cmd_start = .; - .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - __initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start) >> 2; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - __exitcall_entries = (__barebox_exitcalls_end - __barebox_exitcalls_start) >> 2; - - __usymtab_start = .; - __usymtab : { BAREBOX_SYMS } - __usymtab_end = .; - __start___ex_table = .; __ex_table : { *(__ex_table) } __stop___ex_table = .; diff --git a/arch/ppc/mach-mpc85xx/barebox.lds.S b/arch/ppc/mach-mpc85xx/barebox.lds.S index 0001972..a09a01e 100644 --- a/arch/ppc/mach-mpc85xx/barebox.lds.S +++ b/arch/ppc/mach-mpc85xx/barebox.lds.S @@ -71,6 +71,7 @@ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + RO_DATA_SECTION } :text /* Read-write section, merged into data segment: */ @@ -101,29 +102,6 @@ } . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - __barebox_ratp_cmd_start = .; - .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - __initcall_entries = (__barebox_initcalls_end - __barebox_initcalls_start)>>2; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - __exitcall_entries = (__barebox_exitcalls_end - __barebox_exitcalls_start) >> 2; - - __usymtab_start = .; - __usymtab : { BAREBOX_SYMS } - __usymtab_end = .; - - . = .; __start___ex_table = .; __ex_table : { *(__ex_table) } __stop___ex_table = .; diff --git a/arch/riscv/lib/barebox.lds.S b/arch/riscv/lib/barebox.lds.S index ffb97f4..5149f8c 100644 --- a/arch/riscv/lib/barebox.lds.S +++ b/arch/riscv/lib/barebox.lds.S @@ -30,7 +30,10 @@ } . = ALIGN(8); - .rodata : { *(.rodata*) } + .rodata : { + *(.rodata*) + RO_DATA_SECTION + } _etext = .; /* End of text and rodata section */ _sdata = .; @@ -43,32 +46,11 @@ . = ALIGN(8); .got : { *(.got*) } - . = .; - __barebox_cmd_start = .; - .barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - __barebox_initcalls_start = .; - .barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - .barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - __usymtab_start = .; - __usymtab : { BAREBOX_SYMS } - __usymtab_end = .; - .rela.dyn : { *(.rela*) } - .oftables : { BAREBOX_CLK_TABLE() } + .oftables : { BAREBOX_CLK_TABLE } - .dtb : { BAREBOX_DTB() } + .dtb : { BAREBOX_DTB } _edata = .; . = ALIGN(8); diff --git a/arch/sandbox/board/barebox.lds.S b/arch/sandbox/board/barebox.lds.S index 80e27fe..7a5a8eb 100644 --- a/arch/sandbox/board/barebox.lds.S +++ b/arch/sandbox/board/barebox.lds.S @@ -3,29 +3,9 @@ SECTIONS { . = ALIGN(64); - __barebox_initcalls_start = .; - __barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - . = ALIGN(64); - __barebox_exitcalls_start = .; - __barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - . = ALIGN(64); - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - . = ALIGN(64); - __barebox_cmd_start = .; - __barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - . = ALIGN(64); - __barebox_ratp_cmd_start = .; - __barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; + .barebox_rodata : { + RO_DATA_SECTION + } } INSERT BEFORE .rodata; diff --git a/arch/x86/lib/barebox.lds.S b/arch/x86/lib/barebox.lds.S index 6ee9342..7125164 100644 --- a/arch/x86/lib/barebox.lds.S +++ b/arch/x86/lib/barebox.lds.S @@ -133,6 +133,7 @@ *(.boot.rodata*) *(.boot.data*) . = ALIGN(4); + RO_DATA_SECTION } > barebox #endif @@ -164,48 +165,6 @@ . = ALIGN(4); } > barebox - .barebox_cmd : AT ( LOADADDR(.got) + SIZEOF (.got) ) { - __barebox_cmd_start = .; - BAREBOX_CMDS - __barebox_cmd_end = .; - . = ALIGN(4); - } > barebox - - .barebox_ratp_cmd : AT ( LOADADDR(.got) + SIZEOF (.got) ) { - __barebox_ratp_cmd_start = .; - BAREBOX_RATP_CMDS - __barebox_ratp_cmd_end = .; - . = ALIGN(4); - } > barebox - - .barebox_magicvars : AT ( LOADADDR(.barebox_cmd) + SIZEOF (.barebox_cmd) ) { - __barebox_magicvar_start = .; - BAREBOX_MAGICVARS - __barebox_magicvar_end = .; - . = ALIGN(4); - } > barebox - - .barebox_initcalls : AT ( LOADADDR(.barebox_magicvars) + SIZEOF (.barebox_magicvars) ) { - __barebox_initcalls_start = .; - INITCALLS - __barebox_initcalls_end = .; - . = ALIGN(4); - } > barebox - - .barebox_exitcalls : AT ( LOADADDR(.barebox_initcalls) + SIZEOF (.barebox_initcalls) ) { - __barebox_exitcalls_start = .; - EXITCALLS - __barebox_exitcalls_end = .; - . = ALIGN(4); - } > barebox - - .__usymtab : AT ( LOADADDR(.barebox_exitcalls) + SIZEOF (.barebox_exitcalls) ) { - __usymtab_start = .; - BAREBOX_SYMS - __usymtab_end = .; - . = ALIGN(4); - } > barebox - _edata = .; .bss : { __bss_start = .; diff --git a/arch/x86/mach-efi/elf_ia32_efi.lds.S b/arch/x86/mach-efi/elf_ia32_efi.lds.S index 9477aa7..18ddf17 100644 --- a/arch/x86/mach-efi/elf_ia32_efi.lds.S +++ b/arch/x86/mach-efi/elf_ia32_efi.lds.S @@ -35,6 +35,7 @@ .data : { *(.rodata*) + RO_DATA_SECTION *(.data) *(.data1) *(.data.*) @@ -50,31 +51,6 @@ *(COMMON) } - . = ALIGN(64); - - __barebox_initcalls_start = .; - __barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - __barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - . = ALIGN(64); - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - . = ALIGN(64); - __barebox_cmd_start = .; - __barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - . = ALIGN(64); - __barebox_ratp_cmd_start = .; - __barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - . = ALIGN(4096); .dynamic : { *(.dynamic) } . = ALIGN(4096); diff --git a/arch/x86/mach-efi/elf_x86_64_efi.lds.S b/arch/x86/mach-efi/elf_x86_64_efi.lds.S index 90b6b9f..40a9425 100644 --- a/arch/x86/mach-efi/elf_x86_64_efi.lds.S +++ b/arch/x86/mach-efi/elf_x86_64_efi.lds.S @@ -38,6 +38,7 @@ .data : { *(.rodata*) + RO_DATA_SECTION *(.got.plt) *(.got) *(.data*) @@ -52,31 +53,6 @@ *(.rel.local) } - . = ALIGN(64); - - __barebox_initcalls_start = .; - __barebox_initcalls : { INITCALLS } - __barebox_initcalls_end = .; - - __barebox_exitcalls_start = .; - __barebox_exitcalls : { EXITCALLS } - __barebox_exitcalls_end = .; - - . = ALIGN(64); - __barebox_magicvar_start = .; - .barebox_magicvar : { BAREBOX_MAGICVARS } - __barebox_magicvar_end = .; - - . = ALIGN(64); - __barebox_cmd_start = .; - __barebox_cmd : { BAREBOX_CMDS } - __barebox_cmd_end = .; - - . = ALIGN(64); - __barebox_ratp_cmd_start = .; - __barebox_ratp_cmd : { BAREBOX_RATP_CMDS } - __barebox_ratp_cmd_end = .; - . = ALIGN(4096); .dynamic : { *(.dynamic) } . = ALIGN(4096); diff --git a/common/command.c b/common/command.c index d9cc4a6..4984593 100644 --- a/common/command.c +++ b/common/command.c @@ -149,12 +149,12 @@ */ static int init_command_list(void) { - struct command *cmdtp; + struct command * const *cmdtp; - for (cmdtp = &__barebox_cmd_start; - cmdtp != &__barebox_cmd_end; + for (cmdtp = __barebox_cmd_start; + cmdtp != __barebox_cmd_end; cmdtp++) - register_command(cmdtp); + register_command(*cmdtp); return 0; } diff --git a/common/image-fit.c b/common/image-fit.c index 6ac4644..2681d62 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -269,7 +269,7 @@ static int fit_check_rsa_signature(struct device_node *sig_node, enum hash_algo algo, void *hash) { - struct rsa_public_key key = {}; + struct rsa_public_key *key; const char *key_name; char *key_path; struct device_node *key_node; @@ -287,27 +287,34 @@ pr_err("key name not found in %s\n", sig_node->full_name); return -EINVAL; } - key_path = xasprintf("/signature/key-%s", key_name); - key_node = of_find_node_by_path(key_path); - if (!key_node) { - pr_info("failed to find key node %s\n", key_path); + + key = rsa_get_key(key_name); + if (IS_ERR(key)) { + key_path = xasprintf("/signature/key-%s", key_name); + key_node = of_find_node_by_path(key_path); + if (!key_node) { + pr_info("failed to find key node %s\n", key_path); + free(key_path); + return -ENOENT; + } free(key_path); - return -ENOENT; - } - free(key_path); - ret = rsa_of_read_key(key_node, &key); - if (ret) { - pr_info("failed to read key in %s\n", key_node->full_name); - return -ENOENT; + key = rsa_of_read_key(key_node); + + if (IS_ERR(key)) { + pr_info("failed to read key in %s\n", key_node->full_name); + return -ENOENT; + } } - ret = rsa_verify(&key, sig_value, sig_len, hash, algo); + ret = rsa_verify(key, sig_value, sig_len, hash, algo); if (ret) pr_err("image signature BAD\n"); else pr_info("image signature OK\n"); + rsa_key_free(key); + return ret; } diff --git a/crypto/.gitignore b/crypto/.gitignore new file mode 100644 index 0000000..92d8af3 --- /dev/null +++ b/crypto/.gitignore @@ -0,0 +1,2 @@ +rsa-keys.h +rsa-keys.h.tmp diff --git a/crypto/Kconfig b/crypto/Kconfig index c06d3c0..7cc8ace 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -94,6 +94,25 @@ config CRYPTO_RSA bool +config CRYPTO_RSA_BUILTIN_KEYS + bool + default y if CRYPTO_RSA_KEY != "" + +config CRYPTO_RSA_KEY + depends on CRYPTO_RSA + string "RSA key to compile in" + help + This option should be a filename of a PEM-formatted file containing + X.509 certificates to be included into barebox. If the string starts + with "pkcs11:" it is interpreted as a PKCS#11 URI rather than a file. + +config CRYPTO_RSA_KEY_NAME_HINT + depends on CRYPTO_RSA + string "FIT image key name hint" + help + In FIT images keys are identified by a key name hint string. Provide + the key name hint here. + config CRYPTO_KEYSTORE bool "Keystore" help diff --git a/crypto/Makefile b/crypto/Makefile index d6fb74a..3f59de0 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -16,3 +16,13 @@ obj-$(CONFIG_CRYPTO_PBKDF2) += pbkdf2.o obj-$(CONFIG_CRYPTO_RSA) += rsa.o obj-$(CONFIG_CRYPTO_KEYSTORE) += keystore.o + +extra-$(CONFIG_CRYPTO_RSA_BUILTIN_KEYS) += rsa-keys.h + +ifdef CONFIG_CRYPTO_RSA_BUILTIN_KEYS + +$(obj)/rsa.o: $(obj)/rsa-keys.h +$(eval $(call config_filename,CRYPTO_RSA_KEY)) +$(obj)/rsa-keys.h: FORCE + $(call cmd,rsa_keys,$(CONFIG_CRYPTO_RSA_KEY_NAME_HINT):$(CRYPTO_RSA_KEY_SRCPREFIX)$(CRYPTO_RSA_KEY_FILENAME)) +endif diff --git a/crypto/rsa.c b/crypto/rsa.c index 591d15c..6424185 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -380,11 +380,15 @@ dst[i] = fdt32_to_cpu(src[len - 1 - i]); } -int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key) +struct rsa_public_key *rsa_of_read_key(struct device_node *node) { const void *modulus, *rr; const uint64_t *public_exponent; int length; + struct rsa_public_key *key; + int err; + + key = xzalloc(sizeof(*key)); of_property_read_u32(node, "rsa,num-bits", &key->len); of_property_read_u32(node, "rsa,n0-inverse", &key->n0inv); @@ -400,14 +404,16 @@ if (!key->len || !modulus || !rr) { debug("%s: Missing RSA key info", __func__); - return -EFAULT; + err = -EFAULT; + goto out; } /* Sanity check for stack size */ if (key->len > RSA_MAX_KEY_BITS || key->len < RSA_MIN_KEY_BITS) { debug("RSA key bits %u outside allowed range %d..%d\n", key->len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS); - return -EFAULT; + err = -EFAULT; + goto out; } key->len /= sizeof(uint32_t) * 8; @@ -418,5 +424,50 @@ rsa_convert_big_endian(key->modulus, modulus, key->len); rsa_convert_big_endian(key->rr, rr, key->len); - return 0; + err = 0; +out: + if (err) + free(key); + + return err ? ERR_PTR(err) : key; } + +void rsa_key_free(struct rsa_public_key *key) +{ + free(key->modulus); + free(key->rr); + free(key); +} + +#ifdef CONFIG_CRYPTO_RSA_BUILTIN_KEYS +#include "rsa-keys.h" + +extern const struct rsa_public_key * const __rsa_keys_start; +extern const struct rsa_public_key * const __rsa_keys_end; + +struct rsa_public_key *rsa_get_key(const char *name) +{ + const struct rsa_public_key *key; + struct rsa_public_key *new; + const struct rsa_public_key * const *iter; + + for (iter = &__rsa_keys_start; iter != &__rsa_keys_end; iter++) { + key = *iter; + if (!strcmp(name, key->key_name_hint)) + goto found; + } + + return ERR_PTR(-ENOENT); +found: + new = xmemdup(key, sizeof(*key)); + new->modulus = xmemdup(key->modulus, key->len * sizeof(uint32_t)); + new->rr = xmemdup(key->rr, key->len * sizeof(uint32_t)); + + return new; +} +#else +struct rsa_public_key *rsa_get_key(const char *name) +{ + return ERR_PTR(-ENOENT); +} +#endif diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h index 74d3ca4..b6ca8eb 100644 --- a/include/asm-generic/barebox.lds.h +++ b/include/asm-generic/barebox.lds.h @@ -16,7 +16,8 @@ #define PRE_IMAGE #endif -#define INITCALLS \ +#define BAREBOX_INITCALLS \ + __barebox_initcalls_start = .; \ KEEP(*(.initcall.0)) \ KEEP(*(.initcall.1)) \ KEEP(*(.initcall.2)) \ @@ -31,34 +32,47 @@ KEEP(*(.initcall.11)) \ KEEP(*(.initcall.12)) \ KEEP(*(.initcall.13)) \ - KEEP(*(.initcall.14)) + KEEP(*(.initcall.14)) \ + __barebox_initcalls_end = .; -#define EXITCALLS \ +#define BAREBOX_EXITCALLS \ + __barebox_exitcalls_start = .; \ KEEP(*(.exitcall.0)) \ KEEP(*(.exitcall.1)) \ KEEP(*(.exitcall.2)) \ KEEP(*(.exitcall.3)) \ KEEP(*(.exitcall.4)) \ KEEP(*(.exitcall.5)) \ - KEEP(*(.exitcall.6)) + KEEP(*(.exitcall.6)) \ + __barebox_exitcalls_end = .; -#define BAREBOX_CMDS KEEP(*(SORT_BY_NAME(.barebox_cmd*))) +#define BAREBOX_CMDS \ + __barebox_cmd_start = .; \ + KEEP(*(SORT_BY_NAME(.barebox_cmd*))) \ + __barebox_cmd_end = .; -#define BAREBOX_RATP_CMDS KEEP(*(SORT_BY_NAME(.barebox_ratp_cmd*))) +#define BAREBOX_RATP_CMDS \ + __barebox_ratp_cmd_start = .; \ + KEEP(*(SORT_BY_NAME(.barebox_ratp_cmd*))) \ + __barebox_ratp_cmd_end = .; -#define BAREBOX_SYMS KEEP(*(__usymtab)) +#define BAREBOX_SYMS \ + __usymtab_start = .; \ + KEEP(*(__usymtab)) \ + __usymtab_end = .; -#define BAREBOX_MAGICVARS KEEP(*(SORT_BY_NAME(.barebox_magicvar*))) +#define BAREBOX_MAGICVARS \ + __barebox_magicvar_start = .; \ + KEEP(*(SORT_BY_NAME(.barebox_magicvar*))) \ + __barebox_magicvar_end = .; -#define BAREBOX_CLK_TABLE() \ - . = ALIGN(8); \ +#define BAREBOX_CLK_TABLE \ __clk_of_table_start = .; \ KEEP(*(.__clk_of_table)); \ KEEP(*(.__clk_of_table_end)); \ __clk_of_table_end = .; -#define BAREBOX_DTB() \ - . = ALIGN(8); \ +#define BAREBOX_DTB \ __dtb_start = .; \ KEEP(*(.dtb.rodata.*)); \ __dtb_end = .; @@ -69,6 +83,38 @@ *(.barebox_imd_0*) \ KEEP(*(.barebox_imd_end)) +#ifdef CONFIG_PCI +#define BAREBOX_PCI_FIXUP \ + __start_pci_fixups_early = .; \ + KEEP(*(.pci_fixup_early)) \ + __end_pci_fixups_early = .; \ + __start_pci_fixups_header = .; \ + KEEP(*(.pci_fixup_header)) \ + __end_pci_fixups_header = .; \ + __start_pci_fixups_enable = .; \ + KEEP(*(.pci_fixup_enable)) \ + __end_pci_fixups_enable = .; +#else +#define BAREBOX_PCI_FIXUP +#endif + +#define BAREBOX_RSA_KEYS \ + __rsa_keys_start = .; \ + KEEP(*(.rsa_keys.rodata.*)); \ + __rsa_keys_end = .; \ + +#define RO_DATA_SECTION \ + BAREBOX_INITCALLS \ + BAREBOX_EXITCALLS \ + BAREBOX_CMDS \ + BAREBOX_RATP_CMDS \ + BAREBOX_SYMS \ + BAREBOX_MAGICVARS \ + BAREBOX_CLK_TABLE \ + BAREBOX_DTB \ + BAREBOX_RSA_KEYS \ + BAREBOX_PCI_FIXUP + #if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \ CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE #define MAX_BARE_INIT_SIZE CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE diff --git a/include/command.h b/include/command.h index 0afc5c7..7555d00 100644 --- a/include/command.h +++ b/include/command.h @@ -53,15 +53,10 @@ const char *help; /* Help message (long) */ void (*usage)(void); #endif -} -#ifdef __x86_64__ -/* This is required because the linker will put symbols on a 64 bit alignment */ -__attribute__((aligned(64))) -#endif -; +}; -extern struct command __barebox_cmd_start; -extern struct command __barebox_cmd_end; +extern struct command * const __barebox_cmd_start[]; +extern struct command * const __barebox_cmd_end[]; /* common/command.c */ @@ -89,10 +84,12 @@ #endif /* __ASSEMBLY__ */ -#define BAREBOX_CMD_START(_name) \ -extern const struct command __barebox_cmd_##_name; \ -const struct command __barebox_cmd_##_name \ - __attribute__ ((unused,section (".barebox_cmd_" __stringify(_name)))) = { \ +#define BAREBOX_CMD_START(_name) \ +static struct command __barebox_cmd_##_name; \ +const struct command *barebox_cmd_##_name \ + __attribute__ ((unused,section (".barebox_cmd_" __stringify(_name)))) \ + = &__barebox_cmd_##_name; \ +static struct command __barebox_cmd_##_name = { \ .name = #_name, #define BAREBOX_CMD_END \ diff --git a/include/rsa.h b/include/rsa.h index feb8c31..803660d 100644 --- a/include/rsa.h +++ b/include/rsa.h @@ -28,6 +28,7 @@ uint32_t *modulus; /* modulus as little endian array */ uint32_t *rr; /* R^2 as little endian array */ uint64_t exponent; /* public exponent */ + char *key_name_hint; }; /** @@ -49,6 +50,8 @@ /* This is the maximum signature length that we support, in bits */ #define RSA_MAX_SIG_BITS 4096 -int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key); +struct rsa_public_key *rsa_of_read_key(struct device_node *node); +void rsa_key_free(struct rsa_public_key *key); +struct rsa_public_key *rsa_get_key(const char *name); #endif diff --git a/scripts/.gitignore b/scripts/.gitignore index 45c81bf..76ea271 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -29,3 +29,4 @@ omap4_usbboot omap3-usb-loader mips-relocs +rsatoc diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 5f03cf4..fe0de87 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -268,6 +268,55 @@ echo-why = $(call escsq, $(strip $(why))) endif +############################################################################### +# +# When a Kconfig string contains a filename, it is suitable for +# passing to shell commands. It is surrounded by double-quotes, and +# any double-quotes or backslashes within it are escaped by +# backslashes. +# +# This is no use for dependencies or $(wildcard). We need to strip the +# surrounding quotes and the escaping from quotes and backslashes, and +# we *do* need to escape any spaces in the string. So, for example: +# +# Usage: $(eval $(call config_filename,FOO)) +# +# Defines FOO_FILENAME based on the contents of the CONFIG_FOO option, +# transformed as described above to be suitable for use within the +# makefile. +# +# Also, if the filename is a relative filename and exists in the source +# tree but not the build tree, define FOO_SRCPREFIX as $(srctree)/ to +# be prefixed to *both* command invocation and dependencies. +# +# Note: We also print the filenames in the quiet_cmd_foo text, and +# perhaps ought to have a version specially escaped for that purpose. +# But it's only cosmetic, and $(patsubst "%",%,$(CONFIG_FOO)) is good +# enough. It'll strip the quotes in the common case where there's no +# space and it's a simple filename, and it'll retain the quotes when +# there's a space. There are some esoteric cases in which it'll print +# the wrong thing, but we don't really care. The actual dependencies +# and commands *do* get it right, with various combinations of single +# and double quotes, backslashes and spaces in the filenames. +# +############################################################################### +# +define config_filename +ifneq ($$(CONFIG_$(1)),"") +$(1)_FILENAME := $$(subst \\,\,$$(subst \$$(quote),$$(quote),$$(subst $$(space_escape),\$$(space),$$(patsubst "%",%,$$(subst $$(space),$$(space_escape),$$(CONFIG_$(1))))))) +ifneq ($$(patsubst /%,%,$$(firstword $$($(1)_FILENAME))),$$(firstword $$($(1)_FILENAME))) +else +ifeq ($$(wildcard $$($(1)_FILENAME)),) +ifneq ($$(wildcard $$(srctree)/$$($(1)_FILENAME)),) +$(1)_SRCPREFIX := $(srctree)/ +endif +endif +endif +endif +endef +# +############################################################################### + # delete partially updated (i.e. corrupted) files on error .DELETE_ON_ERROR: diff --git a/scripts/Makefile b/scripts/Makefile index 8aaa01f..16bb513 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -10,6 +10,9 @@ hostprogs-y += bareboxenv hostprogs-y += bareboxcrc32 hostprogs-y += kernel-install +hostprogs-$(CONFIG_CRYPTO_RSA_BUILTIN_KEYS) += rsatoc +HOSTCFLAGS_rsatoc = `pkg-config --cflags openssl` +HOSTLDLIBS_rsatoc = `pkg-config --libs openssl` hostprogs-$(CONFIG_IMD) += bareboximd hostprogs-$(CONFIG_KALLSYMS) += kallsyms hostprogs-$(CONFIG_MIPS) += mips-relocs diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index cf9e95c..9aa8be5 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -532,5 +532,22 @@ quiet_cmd_b64dec = B64DEC $@ cmd_b64dec = base64 -d $< > $@ +# rsa_keys +# --------------------------------------------------------------------------- +# Build a header file containing a rsa public key. +# +# The keys can change without the build system noticing, so we always +# have to call rsatoc. To avoid unnecessary rebuilds of barebox compare +# its output to the last rsatoc output. Only if it differs overwrite the +# target file. +quiet_cmd_rsa_keys = RSAKEY $@ +cmd_rsa_keys = \ + $(objtree)/scripts/rsatoc -o $@.tmp $(2) && \ + if cmp -s $@.tmp $@; then \ + rm $@.tmp; \ + else \ + mv $@.tmp $@; \ + fi + %: %.base64 $(call cmd,b64dec) diff --git a/scripts/rsatoc.c b/scripts/rsatoc.c new file mode 100644 index 0000000..6473802 --- /dev/null +++ b/scripts/rsatoc.c @@ -0,0 +1,486 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * rsatoc - utility to convert an RSA key to a C struct + * + * This tool converts an RSA key given as file or PKCS#11 + * URI to a C struct suitable to compile with barebox. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int rsa_err(const char *msg) +{ + unsigned long sslErr = ERR_get_error(); + + fprintf(stderr, "%s", msg); + fprintf(stderr, ": %s\n", + ERR_error_string(sslErr, 0)); + + return -1; +} + +/** + * rsa_pem_get_pub_key() - read a public key from a .crt file + * + * @keydir: Directory containins the key + * @name Name of key file (will have a .crt extension) + * @rsap Returns RSA object, or NULL on failure + * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL) + */ +static int rsa_pem_get_pub_key(const char *path, RSA **rsap) +{ + EVP_PKEY *key; + X509 *cert; + RSA *rsa; + FILE *f; + int ret; + + *rsap = NULL; + f = fopen(path, "r"); + if (!f) { + fprintf(stderr, "Couldn't open RSA certificate: '%s': %s\n", + path, strerror(errno)); + return -EACCES; + } + + /* Read the certificate */ + cert = NULL; + if (!PEM_read_X509(f, &cert, NULL, NULL)) { + rsa_err("Couldn't read certificate"); + ret = -EINVAL; + goto err_cert; + } + + /* Get the public key from the certificate. */ + key = X509_get_pubkey(cert); + if (!key) { + rsa_err("Couldn't read public key\n"); + ret = -EINVAL; + goto err_pubkey; + } + + /* Convert to a RSA_style key. */ + rsa = EVP_PKEY_get1_RSA(key); + if (!rsa) { + rsa_err("Couldn't convert to a RSA style key"); + ret = -EINVAL; + goto err_rsa; + } + fclose(f); + EVP_PKEY_free(key); + X509_free(cert); + *rsap = rsa; + + return 0; + +err_rsa: + EVP_PKEY_free(key); +err_pubkey: + X509_free(cert); +err_cert: + fclose(f); + return ret; +} + +/** + * rsa_engine_get_pub_key() - read a public key from given engine + * + * @keydir: Key prefix + * @name Name of key + * @engine Engine to use + * @rsap Returns RSA object, or NULL on failure + * @return 0 if ok, -ve on error (in which case *rsap will be set to NULL) + */ +static int rsa_engine_get_pub_key(const char *key_id, + ENGINE *engine, RSA **rsap) +{ + EVP_PKEY *key; + RSA *rsa; + int ret; + + *rsap = NULL; + + key = ENGINE_load_public_key(engine, key_id, NULL, NULL); + if (!key) + return rsa_err("Failure loading public key from engine"); + + /* Convert to a RSA_style key. */ + rsa = EVP_PKEY_get1_RSA(key); + if (!rsa) { + rsa_err("Couldn't convert to a RSA style key"); + ret = -EINVAL; + goto err_rsa; + } + + EVP_PKEY_free(key); + *rsap = rsa; + + return 0; + +err_rsa: + EVP_PKEY_free(key); + return ret; +} + +/* + * rsa_get_exponent(): - Get the public exponent from an RSA key + */ +static int rsa_get_exponent(RSA *key, uint64_t *e) +{ + int ret; + BIGNUM *bn_te; + const BIGNUM *key_e; + uint64_t te; + + ret = -EINVAL; + bn_te = NULL; + + if (!e) + goto cleanup; + + RSA_get0_key(key, NULL, &key_e, NULL); + if (BN_num_bits(key_e) > 64) + goto cleanup; + + *e = BN_get_word(key_e); + + if (BN_num_bits(key_e) < 33) { + ret = 0; + goto cleanup; + } + + bn_te = BN_dup(key_e); + if (!bn_te) + goto cleanup; + + if (!BN_rshift(bn_te, bn_te, 32)) + goto cleanup; + + if (!BN_mask_bits(bn_te, 32)) + goto cleanup; + + te = BN_get_word(bn_te); + te <<= 32; + *e |= te; + ret = 0; + +cleanup: + if (bn_te) + BN_free(bn_te); + + return ret; +} + +/* + * rsa_get_params(): - Get the important parameters of an RSA public key + */ +int rsa_get_params(RSA *key, uint64_t *exponent, uint32_t *n0_invp, + BIGNUM **modulusp, BIGNUM **r_squaredp) +{ + BIGNUM *big1, *big2, *big32, *big2_32; + BIGNUM *n, *r, *r_squared, *tmp; + const BIGNUM *key_n; + BN_CTX *bn_ctx = BN_CTX_new(); + int ret = 0; + + /* Initialize BIGNUMs */ + big1 = BN_new(); + big2 = BN_new(); + big32 = BN_new(); + r = BN_new(); + r_squared = BN_new(); + tmp = BN_new(); + big2_32 = BN_new(); + n = BN_new(); + if (!big1 || !big2 || !big32 || !r || !r_squared || !tmp || !big2_32 || + !n) { + fprintf(stderr, "Out of memory (bignum)\n"); + return -ENOMEM; + } + + if (0 != rsa_get_exponent(key, exponent)) + ret = -1; + + RSA_get0_key(key, &key_n, NULL, NULL); + if (!BN_copy(n, key_n) || !BN_set_word(big1, 1L) || + !BN_set_word(big2, 2L) || !BN_set_word(big32, 32L)) + ret = -1; + + /* big2_32 = 2^32 */ + if (!BN_exp(big2_32, big2, big32, bn_ctx)) + ret = -1; + + /* Calculate n0_inv = -1 / n[0] mod 2^32 */ + if (!BN_mod_inverse(tmp, n, big2_32, bn_ctx) || + !BN_sub(tmp, big2_32, tmp)) + ret = -1; + *n0_invp = BN_get_word(tmp); + + /* Calculate R = 2^(# of key bits) */ + if (!BN_set_word(tmp, BN_num_bits(n)) || + !BN_exp(r, big2, tmp, bn_ctx)) + ret = -1; + + /* Calculate r_squared = R^2 mod n */ + if (!BN_copy(r_squared, r) || + !BN_mul(tmp, r_squared, r, bn_ctx) || + !BN_mod(r_squared, tmp, n, bn_ctx)) + ret = -1; + + *modulusp = n; + *r_squaredp = r_squared; + + BN_free(big1); + BN_free(big2); + BN_free(big32); + BN_free(r); + BN_free(tmp); + BN_free(big2_32); + if (ret) { + fprintf(stderr, "Bignum operations failed\n"); + return -ENOMEM; + } + + return ret; +} + +static int rsa_engine_init(ENGINE **pe) +{ + ENGINE *e; + int ret; + const char *key_pass = getenv("KBUILD_SIGN_PIN"); + + ENGINE_load_builtin_engines(); + + e = ENGINE_by_id("pkcs11"); + if (!e) { + fprintf(stderr, "Engine isn't available\n"); + ret = -1; + goto err_engine_by_id; + } + + if (!ENGINE_init(e)) { + fprintf(stderr, "Couldn't initialize engine\n"); + ret = -1; + goto err_engine_init; + } + + if (key_pass) { + if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) { + fprintf(stderr, "Cannot set PKCS#11 PIN\n"); + goto err_set_rsa; + } + } + + if (!ENGINE_set_default_RSA(e)) { + fprintf(stderr, "Couldn't set engine as default for RSA\n"); + ret = -1; + goto err_set_rsa; + } + + *pe = e; + + return 0; + +err_set_rsa: + ENGINE_finish(e); +err_engine_init: + ENGINE_free(e); +err_engine_by_id: +#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL) + ENGINE_cleanup(); +#endif + return ret; +} + +static FILE *outfilep; + +static int print_bignum(BIGNUM *num, int num_bits) +{ + BIGNUM *tmp, *big2, *big32, *big2_32; + BN_CTX *ctx; + int i; + + tmp = BN_new(); + big2 = BN_new(); + big32 = BN_new(); + big2_32 = BN_new(); + + /* + * Note: This code assumes that all of the above succeed, or all fail. + * In practice memory allocations generally do not fail (unless the + * process is killed), so it does not seem worth handling each of these + * as a separate case. Technicaly this could leak memory on failure, + * but a) it won't happen in practice, and b) it doesn't matter as we + * will immediately exit with a failure code. + */ + if (!tmp || !big2 || !big32 || !big2_32) { + fprintf(stderr, "Out of memory (bignum)\n"); + return -ENOMEM; + } + ctx = BN_CTX_new(); + if (!tmp) { + fprintf(stderr, "Out of memory (bignum context)\n"); + return -ENOMEM; + } + BN_set_word(big2, 2L); + BN_set_word(big32, 32L); + BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */ + + for (i = 0; i < num_bits / 32; i++) { + BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */ + if (i % 4) + fprintf(outfilep, " "); + else + fprintf(outfilep, "\n\t"); + fprintf(outfilep, "0x%08lx,", BN_get_word(tmp)); + BN_rshift(num, num, 32); /* N = N/B */ + } + + BN_free(tmp); + BN_free(big2); + BN_free(big32); + BN_free(big2_32); + + return 0; +} + +static int gen_key(const char *keyname, const char *path) +{ + BIGNUM *modulus, *r_squared; + uint64_t exponent; + uint32_t n0_inv; + int ret; + int bits; + RSA *rsa; + ENGINE *e = NULL; + char *tmp, *key_name_c; + + tmp = key_name_c = strdup(keyname); + + while (*tmp) { + if (*tmp == '-') + *tmp = '_'; + tmp++; + } + + if (!strncmp(path, "__ENV__", 7)) { + const char *var = getenv(path + 7); + if (!var) { + fprintf(stderr, + "environment variable \"%s\" is empty\n", path + 7); + exit(1); + } + path = var; + } + + if (!strncmp(path, "pkcs11:", 7)) { + ret = rsa_engine_init(&e); + if (ret) + exit(1); + ret = rsa_engine_get_pub_key(path, e, &rsa); + if (ret) + exit(1); + } else { + ret = rsa_pem_get_pub_key(path, &rsa); + if (ret) + exit(1); + } + + ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus, &r_squared); + if (ret) + return ret; + + bits = BN_num_bits(modulus); + + fprintf(outfilep, "\nstatic uint32_t %s_modulus[] = {", key_name_c); + print_bignum(modulus, bits); + fprintf(outfilep, "\n};\n\n"); + + fprintf(outfilep, "static uint32_t %s_rr[] = {", key_name_c); + print_bignum(r_squared, bits); + fprintf(outfilep, "\n};\n\n"); + + fprintf(outfilep, "static struct rsa_public_key %s = {\n", key_name_c); + fprintf(outfilep, "\t.len = %d,\n", bits / 32); + fprintf(outfilep, "\t.n0inv = 0x%0x,\n", n0_inv); + fprintf(outfilep, "\t.modulus = %s_modulus,\n", key_name_c); + fprintf(outfilep, "\t.rr = %s_rr,\n", key_name_c); + fprintf(outfilep, "\t.exponent = 0x%0lx,\n", exponent); + fprintf(outfilep, "\t.key_name_hint = \"%s\",\n", keyname); + fprintf(outfilep, "};\n\n"); + + fprintf(outfilep, "struct rsa_public_key *%sp __attribute__((section(\".rsa_keys.rodata.%s\"))) = &%s;\n", + key_name_c, key_name_c, key_name_c); + + return 0; +} + +int main(int argc, char *argv[]) +{ + char *path, *keyname; + int i, opt; + char *outfile = NULL; + + outfilep = stdout; + + while ((opt = getopt(argc, argv, "o:")) > 0) { + switch (opt) { + case 'o': + outfile = optarg; + break; + } + } + + if (outfile) { + outfilep = fopen(outfile, "w"); + if (!outfilep) { + fprintf(stderr, "cannot open %s: %s\n", outfile, + strerror(errno)); + exit(1); + } + } + + if (optind == argc) { + fprintf(stderr, "Usage: %s : ...\n", argv[0]); + exit(1); + } + + for (i = optind; i < argc; i++) { + keyname = argv[i]; + + path = strchr(keyname, ':'); + if (!path) { + fprintf(stderr, + "keys must be given as :\n"); + exit(1); + } + + *path = 0; + path++; + + if (!strncmp(path, "__ENV__", 7)) { + path = getenv(path + 7); + if (!path) { + fprintf(stderr, "%s doesn't contain a path\n", + path + 7); + exit(1); + } + } + + gen_key(keyname, path); + } + + exit(0); +}