diff options
-rw-r--r-- | scripts/Makefile.modpost | 77 | ||||
-rw-r--r-- | scripts/sign-file | 115 |
2 files changed, 191 insertions, 1 deletions
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 08dce14f2dc8..2a4d1a176526 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
@@ -14,7 +14,8 @@ | |||
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> file | 17 | # 6) final link of the module to a <module.ko> (or <module.unsigned>) file |
18 | # 7) signs the modules to a <module.ko> file | ||
18 | 19 | ||
19 | # Step 3 is used to place certain information in the module's ELF | 20 | # Step 3 is used to place certain information in the module's ELF |
20 | # section, including information such as: | 21 | # section, including information such as: |
@@ -32,6 +33,8 @@ | |||
32 | # Step 4 is solely used to allow module versioning in external modules, | 33 | # Step 4 is solely used to allow module versioning in external modules, |
33 | # where the CRC of each module is retrieved from the Module.symvers file. | 34 | # where the CRC of each module is retrieved from the Module.symvers file. |
34 | 35 | ||
36 | # Step 7 is dependent on CONFIG_MODULE_SIG being enabled. | ||
37 | |||
35 | # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined | 38 | # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined |
36 | # symbols in the final module linking stage | 39 | # symbols in the final module linking stage |
37 | # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. | 40 | # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. |
@@ -116,6 +119,7 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE | |||
116 | targets += $(modules:.ko=.mod.o) | 119 | targets += $(modules:.ko=.mod.o) |
117 | 120 | ||
118 | # Step 6), final link of the modules | 121 | # Step 6), final link of the modules |
122 | ifneq ($(CONFIG_MODULE_SIG),y) | ||
119 | quiet_cmd_ld_ko_o = LD [M] $@ | 123 | quiet_cmd_ld_ko_o = LD [M] $@ |
120 | cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \ | 124 | cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \ |
121 | $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ | 125 | $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ |
@@ -125,7 +129,78 @@ $(modules): %.ko :%.o %.mod.o FORCE | |||
125 | $(call if_changed,ld_ko_o) | 129 | $(call if_changed,ld_ko_o) |
126 | 130 | ||
127 | targets += $(modules) | 131 | 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 | ||
128 | 165 | ||
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 | ||
129 | 204 | ||
130 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. | 205 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. |
131 | # --------------------------------------------------------------------------- | 206 | # --------------------------------------------------------------------------- |
diff --git a/scripts/sign-file b/scripts/sign-file new file mode 100644 index 000000000000..e58e34e50ac5 --- /dev/null +++ b/scripts/sign-file | |||
@@ -0,0 +1,115 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # Sign a module file using the given key. | ||
4 | # | ||
5 | # Format: sign-file <key> <x509> <src-file> <dst-file> | ||
6 | # | ||
7 | |||
8 | scripts=`dirname $0` | ||
9 | |||
10 | CONFIG_MODULE_SIG_SHA512=y | ||
11 | if [ -r .config ] | ||
12 | then | ||
13 | . ./.config | ||
14 | fi | ||
15 | |||
16 | key="$1" | ||
17 | x509="$2" | ||
18 | src="$3" | ||
19 | dst="$4" | ||
20 | |||
21 | if [ ! -r "$key" ] | ||
22 | then | ||
23 | echo "Can't read private key" >&2 | ||
24 | exit 2 | ||
25 | fi | ||
26 | |||
27 | if [ ! -r "$x509" ] | ||
28 | then | ||
29 | echo "Can't read X.509 certificate" >&2 | ||
30 | exit 2 | ||
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 | |||
43 | # | ||
44 | # Signature parameters | ||
45 | # | ||
46 | algo=1 # Public-key crypto algorithm: RSA | ||
47 | hash= # Digest algorithm | ||
48 | id_type=1 # Identifier type: X.509 | ||
49 | |||
50 | # | ||
51 | # Digest the data | ||
52 | # | ||
53 | dgst= | ||
54 | if [ "$CONFIG_MODULE_SIG_SHA1" = "y" ] | ||
55 | then | ||
56 | prologue="0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14" | ||
57 | dgst=-sha1 | ||
58 | hash=2 | ||
59 | elif [ "$CONFIG_MODULE_SIG_SHA224" = "y" ] | ||
60 | then | ||
61 | prologue="0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C" | ||
62 | dgst=-sha224 | ||
63 | hash=7 | ||
64 | elif [ "$CONFIG_MODULE_SIG_SHA256" = "y" ] | ||
65 | then | ||
66 | prologue="0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20" | ||
67 | dgst=-sha256 | ||
68 | hash=4 | ||
69 | elif [ "$CONFIG_MODULE_SIG_SHA384" = "y" ] | ||
70 | then | ||
71 | prologue="0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30" | ||
72 | dgst=-sha384 | ||
73 | hash=5 | ||
74 | elif [ "$CONFIG_MODULE_SIG_SHA512" = "y" ] | ||
75 | then | ||
76 | prologue="0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40" | ||
77 | dgst=-sha512 | ||
78 | hash=6 | ||
79 | else | ||
80 | echo "$0: Can't determine hash algorithm" >&2 | ||
81 | exit 2 | ||
82 | fi | ||
83 | |||
84 | ( | ||
85 | perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $? | ||
86 | openssl dgst $dgst -binary $src || exit $? | ||
87 | ) >$src.dig || exit $? | ||
88 | |||
89 | # | ||
90 | # Generate the binary signature, which will be just the integer that comprises | ||
91 | # the signature with no metadata attached. | ||
92 | # | ||
93 | openssl rsautl -sign -inkey $key -keyform PEM -in $src.dig -out $src.sig || exit $? | ||
94 | signerlen=`stat -c %s $x509.signer` | ||
95 | keyidlen=`stat -c %s $x509.keyid` | ||
96 | siglen=`stat -c %s $src.sig` | ||
97 | |||
98 | # | ||
99 | # Build the signed binary | ||
100 | # | ||
101 | ( | ||
102 | cat $src || exit $? | ||
103 | echo '~Module signature appended~' || exit $? | ||
104 | cat $x509.signer $x509.keyid || exit $? | ||
105 | |||
106 | # Preface each signature integer with a 2-byte BE length | ||
107 | perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $? | ||
108 | cat $src.sig || exit $? | ||
109 | |||
110 | # Generate the information block | ||
111 | perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $? | ||
112 | ) >$dst~ || exit $? | ||
113 | |||
114 | # Permit in-place signing | ||
115 | mv $dst~ $dst || exit $? | ||