diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2012-10-18 21:23:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-19 11:27:43 -0400 |
commit | e2a666d52b4825c26c857cada211f3baac26a600 (patch) | |
tree | b7e91bd10e8c1b2932ffd1716fde3abccd7c4dd8 /scripts | |
parent | c9623de4fc2f8320fe94316b46171683be3b1d59 (diff) |
kbuild: sign the modules at install time
Linus deleted the old code and put signing on the install command,
I fixed it to extract the keyid and signer-name within sign-file
and cleaned up that script now it always signs in-place.
Some enthusiast should convert sign-key to perl and pull
x509keyid into it.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile.modinst | 2 | ||||
-rw-r--r-- | scripts/Makefile.modpost | 77 | ||||
-rw-r--r-- | scripts/sign-file | 44 | ||||
-rwxr-xr-x | scripts/x509keyid | 16 |
4 files changed, 28 insertions, 111 deletions
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 3d13d3a3edfe..dda4b2b61927 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst | |||
@@ -17,7 +17,7 @@ __modinst: $(modules) | |||
17 | @: | 17 | @: |
18 | 18 | ||
19 | quiet_cmd_modules_install = INSTALL $@ | 19 | quiet_cmd_modules_install = INSTALL $@ |
20 | cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) | 20 | cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) |
21 | 21 | ||
22 | # Modules built outside the kernel source tree go into extra by default | 22 | # Modules built outside the kernel source tree go into extra by default |
23 | INSTALL_MOD_DIR ?= extra | 23 | INSTALL_MOD_DIR ?= extra |
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 002089141df4..a1cb0222ebe6 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
@@ -14,8 +14,7 @@ | |||
14 | # 3) create one <module>.mod.c file pr. module | 14 | # 3) create one <module>.mod.c file pr. module |
15 | # 4) create one Module.symvers file with CRC for all exported symbols | 15 | # 4) create one Module.symvers file with CRC for all exported symbols |
16 | # 5) compile all <module>.mod.c files | 16 | # 5) compile all <module>.mod.c files |
17 | # 6) final link of the module to a <module.ko> (or <module.unsigned>) file | 17 | # 6) final link of the module to a <module.ko> file |
18 | # 7) signs the modules to a <module.ko> file | ||
19 | 18 | ||
20 | # Step 3 is used to place certain information in the module's ELF | 19 | # Step 3 is used to place certain information in the module's ELF |
21 | # section, including information such as: | 20 | # section, including information such as: |
@@ -33,8 +32,6 @@ | |||
33 | # Step 4 is solely used to allow module versioning in external modules, | 32 | # Step 4 is solely used to allow module versioning in external modules, |
34 | # where the CRC of each module is retrieved from the Module.symvers file. | 33 | # where the CRC of each module is retrieved from the Module.symvers file. |
35 | 34 | ||
36 | # Step 7 is dependent on CONFIG_MODULE_SIG being enabled. | ||
37 | |||
38 | # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined | 35 | # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined |
39 | # symbols in the final module linking stage | 36 | # symbols in the final module linking stage |
40 | # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. | 37 | # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. |
@@ -119,7 +116,6 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE | |||
119 | targets += $(modules:.ko=.mod.o) | 116 | targets += $(modules:.ko=.mod.o) |
120 | 117 | ||
121 | # Step 6), final link of the modules | 118 | # Step 6), final link of the modules |
122 | ifneq ($(CONFIG_MODULE_SIG),y) | ||
123 | quiet_cmd_ld_ko_o = LD [M] $@ | 119 | quiet_cmd_ld_ko_o = LD [M] $@ |
124 | cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \ | 120 | cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \ |
125 | $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ | 121 | $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ |
@@ -129,78 +125,7 @@ $(modules): %.ko :%.o %.mod.o FORCE | |||
129 | $(call if_changed,ld_ko_o) | 125 | $(call if_changed,ld_ko_o) |
130 | 126 | ||
131 | targets += $(modules) | 127 | targets += $(modules) |
132 | else | ||
133 | quiet_cmd_ld_ko_unsigned_o = LD [M] $@ | ||
134 | cmd_ld_ko_unsigned_o = \ | ||
135 | $(LD) -r $(LDFLAGS) \ | ||
136 | $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ | ||
137 | -o $@ $(filter-out FORCE,$^) \ | ||
138 | $(if $(AFTER_LINK),; $(AFTER_LINK)) | ||
139 | |||
140 | $(modules:.ko=.ko.unsigned): %.ko.unsigned :%.o %.mod.o FORCE | ||
141 | $(call if_changed,ld_ko_unsigned_o) | ||
142 | |||
143 | targets += $(modules:.ko=.ko.unsigned) | ||
144 | |||
145 | # Step 7), sign the modules | ||
146 | MODSECKEY = ./signing_key.priv | ||
147 | MODPUBKEY = ./signing_key.x509 | ||
148 | |||
149 | ifeq ($(wildcard $(MODSECKEY))+$(wildcard $(MODPUBKEY)),$(MODSECKEY)+$(MODPUBKEY)) | ||
150 | ifeq ($(KBUILD_SRC),) | ||
151 | # no O= is being used | ||
152 | SCRIPTS_DIR := scripts | ||
153 | else | ||
154 | SCRIPTS_DIR := $(KBUILD_SRC)/scripts | ||
155 | endif | ||
156 | SIGN_MODULES := 1 | ||
157 | else | ||
158 | SIGN_MODULES := 0 | ||
159 | endif | ||
160 | |||
161 | # only sign if it's an in-tree module | ||
162 | ifneq ($(KBUILD_EXTMOD),) | ||
163 | SIGN_MODULES := 0 | ||
164 | endif | ||
165 | 128 | ||
166 | # We strip the module as best we can - note that using both strip and eu-strip | ||
167 | # results in a smaller module than using either alone. | ||
168 | EU_STRIP = $(shell which eu-strip || echo true) | ||
169 | |||
170 | quiet_cmd_sign_ko_stripped_ko_unsigned = STRIP [M] $@ | ||
171 | cmd_sign_ko_stripped_ko_unsigned = \ | ||
172 | cp $< $@ && \ | ||
173 | strip -x -g $@ && \ | ||
174 | $(EU_STRIP) $@ | ||
175 | |||
176 | ifeq ($(SIGN_MODULES),1) | ||
177 | |||
178 | quiet_cmd_genkeyid = GENKEYID $@ | ||
179 | cmd_genkeyid = \ | ||
180 | perl $(SCRIPTS_DIR)/x509keyid $< $<.signer $<.keyid | ||
181 | |||
182 | %.signer %.keyid: % | ||
183 | $(call if_changed,genkeyid) | ||
184 | |||
185 | KEYRING_DEP := $(MODSECKEY) $(MODPUBKEY) $(MODPUBKEY).signer $(MODPUBKEY).keyid | ||
186 | quiet_cmd_sign_ko_ko_stripped = SIGN [M] $@ | ||
187 | cmd_sign_ko_ko_stripped = \ | ||
188 | sh $(SCRIPTS_DIR)/sign-file $(MODSECKEY) $(MODPUBKEY) $< $@ | ||
189 | else | ||
190 | KEYRING_DEP := | ||
191 | quiet_cmd_sign_ko_ko_unsigned = NO SIGN [M] $@ | ||
192 | cmd_sign_ko_ko_unsigned = \ | ||
193 | cp $< $@ | ||
194 | endif | ||
195 | |||
196 | $(modules): %.ko :%.ko.stripped $(KEYRING_DEP) FORCE | ||
197 | $(call if_changed,sign_ko_ko_stripped) | ||
198 | |||
199 | $(patsubst %.ko,%.ko.stripped,$(modules)): %.ko.stripped :%.ko.unsigned FORCE | ||
200 | $(call if_changed,sign_ko_stripped_ko_unsigned) | ||
201 | |||
202 | targets += $(modules) | ||
203 | endif | ||
204 | 129 | ||
205 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. | 130 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. |
206 | # --------------------------------------------------------------------------- | 131 | # --------------------------------------------------------------------------- |
diff --git a/scripts/sign-file b/scripts/sign-file index e58e34e50ac5..095a953bdb8e 100644 --- a/scripts/sign-file +++ b/scripts/sign-file | |||
@@ -1,8 +1,8 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/bash |
2 | # | 2 | # |
3 | # Sign a module file using the given key. | 3 | # Sign a module file using the given key. |
4 | # | 4 | # |
5 | # Format: sign-file <key> <x509> <src-file> <dst-file> | 5 | # Format: sign-file <key> <x509> <keyid-script> <module> |
6 | # | 6 | # |
7 | 7 | ||
8 | scripts=`dirname $0` | 8 | scripts=`dirname $0` |
@@ -15,8 +15,8 @@ fi | |||
15 | 15 | ||
16 | key="$1" | 16 | key="$1" |
17 | x509="$2" | 17 | x509="$2" |
18 | src="$3" | 18 | keyid_script="$3" |
19 | dst="$4" | 19 | mod="$4" |
20 | 20 | ||
21 | if [ ! -r "$key" ] | 21 | if [ ! -r "$key" ] |
22 | then | 22 | then |
@@ -29,16 +29,6 @@ then | |||
29 | echo "Can't read X.509 certificate" >&2 | 29 | echo "Can't read X.509 certificate" >&2 |
30 | exit 2 | 30 | exit 2 |
31 | fi | 31 | fi |
32 | if [ ! -r "$x509.signer" ] | ||
33 | then | ||
34 | echo "Can't read Signer name" >&2 | ||
35 | exit 2; | ||
36 | fi | ||
37 | if [ ! -r "$x509.keyid" ] | ||
38 | then | ||
39 | echo "Can't read Key identifier" >&2 | ||
40 | exit 2; | ||
41 | fi | ||
42 | 32 | ||
43 | # | 33 | # |
44 | # Signature parameters | 34 | # Signature parameters |
@@ -83,33 +73,35 @@ fi | |||
83 | 73 | ||
84 | ( | 74 | ( |
85 | perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $? | 75 | perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $? |
86 | openssl dgst $dgst -binary $src || exit $? | 76 | openssl dgst $dgst -binary $mod || exit $? |
87 | ) >$src.dig || exit $? | 77 | ) >$mod.dig || exit $? |
88 | 78 | ||
89 | # | 79 | # |
90 | # Generate the binary signature, which will be just the integer that comprises | 80 | # Generate the binary signature, which will be just the integer that comprises |
91 | # the signature with no metadata attached. | 81 | # the signature with no metadata attached. |
92 | # | 82 | # |
93 | openssl rsautl -sign -inkey $key -keyform PEM -in $src.dig -out $src.sig || exit $? | 83 | openssl rsautl -sign -inkey $key -keyform PEM -in $mod.dig -out $mod.sig || exit $? |
94 | signerlen=`stat -c %s $x509.signer` | 84 | |
95 | keyidlen=`stat -c %s $x509.keyid` | 85 | SIGNER="`perl $keyid_script $x509 signer-name`" |
96 | siglen=`stat -c %s $src.sig` | 86 | KEYID="`perl $keyid_script $x509 keyid`" |
87 | keyidlen=${#KEYID} | ||
88 | siglen=${#SIGNER} | ||
97 | 89 | ||
98 | # | 90 | # |
99 | # Build the signed binary | 91 | # Build the signed binary |
100 | # | 92 | # |
101 | ( | 93 | ( |
102 | cat $src || exit $? | 94 | cat $mod || exit $? |
103 | echo '~Module signature appended~' || exit $? | 95 | echo '~Module signature appended~' || exit $? |
104 | cat $x509.signer $x509.keyid || exit $? | 96 | echo -n "$SIGNER" || exit $? |
97 | echo -n "$KEYID" || exit $? | ||
105 | 98 | ||
106 | # Preface each signature integer with a 2-byte BE length | 99 | # Preface each signature integer with a 2-byte BE length |
107 | perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $? | 100 | perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $? |
108 | cat $src.sig || exit $? | 101 | cat $mod.sig || exit $? |
109 | 102 | ||
110 | # Generate the information block | 103 | # Generate the information block |
111 | perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $? | 104 | perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $? |
112 | ) >$dst~ || exit $? | 105 | ) >$mod~ || exit $? |
113 | 106 | ||
114 | # Permit in-place signing | 107 | mv $mod~ $mod || exit $? |
115 | mv $dst~ $dst || exit $? | ||
diff --git a/scripts/x509keyid b/scripts/x509keyid index c8e91a4af385..4241ec6c64b1 100755 --- a/scripts/x509keyid +++ b/scripts/x509keyid | |||
@@ -22,7 +22,7 @@ use strict; | |||
22 | 22 | ||
23 | my $raw_data; | 23 | my $raw_data; |
24 | 24 | ||
25 | die "Need three filenames\n" if ($#ARGV != 2); | 25 | die "Need a filename [keyid|signer-name]\n" if ($#ARGV != 1); |
26 | 26 | ||
27 | my $src = $ARGV[0]; | 27 | my $src = $ARGV[0]; |
28 | 28 | ||
@@ -259,10 +259,10 @@ die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n" | |||
259 | 259 | ||
260 | my $id_key_id = asn1_retrieve($subject_key_id->[1]); | 260 | my $id_key_id = asn1_retrieve($subject_key_id->[1]); |
261 | 261 | ||
262 | open(OUTFD, ">$ARGV[1]") || die $ARGV[1]; | 262 | if ($ARGV[1] eq "signer-name") { |
263 | print OUTFD $id_name; | 263 | print $id_name; |
264 | close OUTFD || die $ARGV[1]; | 264 | } elsif ($ARGV[1] eq "keyid") { |
265 | 265 | print $id_key_id; | |
266 | open(OUTFD, ">$ARGV[2]") || die $ARGV[2]; | 266 | } else { |
267 | print OUTFD $id_key_id; | 267 | die "Unknown arg"; |
268 | close OUTFD || die $ARGV[2]; | 268 | } |