xref: /OK3568_Linux_fs/buildroot/package/crda/0001-crda-support-python-3-in-utils-key2pub.py.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunFrom 8228c484a1533ff904b276c342adcb6310abe272 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Taahir Ahmed <ahmed.taahir@gmail.com>
3*4882a593SmuzhiyunDate: Wed, 30 Mar 2016 11:23:54 -0300
4*4882a593SmuzhiyunSubject: [PATCH] crda: support python 3 in utils/key2pub.py
5*4882a593Smuzhiyun
6*4882a593Smuzhiyunutils/key2pub.py can now be run under either python 2.7 or python 3.x.
7*4882a593SmuzhiyunThis required some minor syntactical changes as well as switching from
8*4882a593SmuzhiyunM2Crypto to pycryptodomex, since M2Crypto doesn't support python 3.x.
9*4882a593Smuzhiyun
10*4882a593SmuzhiyunIn addition, some errors in the generated source file keys-ssl.h are
11*4882a593Smuzhiyunfixed:
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun  * The correct OpenSSL header for BN_ULONG is included.
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun  * The generated constants are given the 'ull' suffix to prevent
16*4882a593Smuzhiyun    warnings about constants that are too large.
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun[Gustavo: don't call /utils/key2pub.py since that doesn't compute]
19*4882a593Smuzhiyun
20*4882a593SmuzhiyunUse pycryptodomex insdead of pycrypto
21*4882a593Smuzhiyun
22*4882a593SmuzhiyunFrom [1]:
23*4882a593Smuzhiyun"PyCryptodome is a fork of PyCrypto, which is not maintained any more
24*4882a593Smuzhiyun(the last release dates back to 2013 [2]). It exposes almost the same
25*4882a593SmuzhiyunAPI, but there are a few incompatibilities [3]."
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun[1] https://github.com/OP-TEE/optee_os/commit/90ad2450436fdd9fc0d28a3f92f3fbcfd89a38f0
28*4882a593Smuzhiyun[2] https://pypi.org/project/pycrypto/#history
29*4882a593Smuzhiyun[3] https://pycryptodome.readthedocs.io/en/latest/src/vs_pycrypto.html
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunSigned-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
32*4882a593Smuzhiyun[Rebased against crda-4.14]
33*4882a593SmuzhiyunSigned-off-by: Peter Seiderer <ps.report@gmx.net>
34*4882a593Smuzhiyun[Romain: Use pycryptodomex]
35*4882a593SmuzhiyunSigned-off-by: Romain Naour <romain.naour@gmail.com>
36*4882a593Smuzhiyun---
37*4882a593Smuzhiyun Makefile         |   2 +-
38*4882a593Smuzhiyun utils/key2pub.py | 146 ++++++++++++++++++++++++-----------------------
39*4882a593Smuzhiyun 2 files changed, 75 insertions(+), 73 deletions(-)
40*4882a593Smuzhiyun
41*4882a593Smuzhiyundiff --git a/Makefile b/Makefile
42*4882a593Smuzhiyunindex a3ead30..8da38d0 100644
43*4882a593Smuzhiyun--- a/Makefile
44*4882a593Smuzhiyun+++ b/Makefile
45*4882a593Smuzhiyun@@ -112,7 +112,7 @@ $(REG_BIN):
46*4882a593Smuzhiyun keys-%.c: utils/key2pub.py $(wildcard $(PUBKEY_DIR)/*.pem)
47*4882a593Smuzhiyun 	$(NQ) '  GEN ' $@
48*4882a593Smuzhiyun 	$(NQ) '  Trusted pubkeys:' $(wildcard $(PUBKEY_DIR)/*.pem)
49*4882a593Smuzhiyun-	$(Q)./utils/key2pub.py --$* $(wildcard $(PUBKEY_DIR)/*.pem) $@
50*4882a593Smuzhiyun+	$(Q) python utils/key2pub.py --$* $(wildcard $(PUBKEY_DIR)/*.pem) $@
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun $(LIBREG): regdb.h reglib.h reglib.c
53*4882a593Smuzhiyun 	$(NQ) '  CC  ' $@
54*4882a593Smuzhiyundiff --git a/utils/key2pub.py b/utils/key2pub.py
55*4882a593Smuzhiyunindex 9bb04cd..8a0ba2a 100755
56*4882a593Smuzhiyun--- a/utils/key2pub.py
57*4882a593Smuzhiyun+++ b/utils/key2pub.py
58*4882a593Smuzhiyun@@ -1,126 +1,128 @@
59*4882a593Smuzhiyun #!/usr/bin/env python
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun+import io
62*4882a593Smuzhiyun import sys
63*4882a593Smuzhiyun try:
64*4882a593Smuzhiyun-       from M2Crypto import RSA
65*4882a593Smuzhiyun-except ImportError, e:
66*4882a593Smuzhiyun-       sys.stderr.write('ERROR: Failed to import the "M2Crypto" module: %s\n' % e.message)
67*4882a593Smuzhiyun-       sys.stderr.write('Please install the "M2Crypto" Python module.\n')
68*4882a593Smuzhiyun-       sys.stderr.write('On Debian GNU/Linux the package is called "python-m2crypto".\n')
69*4882a593Smuzhiyun-       sys.exit(1)
70*4882a593Smuzhiyun+    from Cryptodome.PublicKey import RSA
71*4882a593Smuzhiyun+except ImportError as e:
72*4882a593Smuzhiyun+    sys.stderr.write('ERROR: Failed to import the "Cryptodome.PublicKey" module: %s\n' % e.message)
73*4882a593Smuzhiyun+    sys.stderr.write('Please install the "Cryptodome.PublicKey" Python module.\n')
74*4882a593Smuzhiyun+    sys.stderr.write('On Debian GNU/Linux the package is called "python-cryptodomex".\n')
75*4882a593Smuzhiyun+    sys.exit(1)
76*4882a593Smuzhiyun+
77*4882a593Smuzhiyun+def bitwise_collect(value, radix_bits):
78*4882a593Smuzhiyun+    words = []
79*4882a593Smuzhiyun+    radix_mask = (1 << radix_bits) - 1
80*4882a593Smuzhiyun+    while value != 0:
81*4882a593Smuzhiyun+        words.append(value & radix_mask)
82*4882a593Smuzhiyun+        value >>= radix_bits
83*4882a593Smuzhiyun+    return words
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun def print_ssl_64(output, name, val):
86*4882a593Smuzhiyun-    while val[0] == '\0':
87*4882a593Smuzhiyun-        val = val[1:]
88*4882a593Smuzhiyun-    while len(val) % 8:
89*4882a593Smuzhiyun-        val = '\0' + val
90*4882a593Smuzhiyun-    vnew = []
91*4882a593Smuzhiyun-    while len(val):
92*4882a593Smuzhiyun-        vnew.append((val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]))
93*4882a593Smuzhiyun-        val = val[8:]
94*4882a593Smuzhiyun-    vnew.reverse()
95*4882a593Smuzhiyun-    output.write('static BN_ULONG %s[%d] = {\n' % (name, len(vnew)))
96*4882a593Smuzhiyun+    # OpenSSL expects 64-bit words given least-significant-word first.
97*4882a593Smuzhiyun+    vwords = bitwise_collect(val, 64)
98*4882a593Smuzhiyun+
99*4882a593Smuzhiyun+    output.write(u'static BN_ULONG {}[] = {{\n'.format(name))
100*4882a593Smuzhiyun     idx = 0
101*4882a593Smuzhiyun-    for v1, v2, v3, v4, v5, v6, v7, v8 in vnew:
102*4882a593Smuzhiyun+    for vword in vwords:
103*4882a593Smuzhiyun         if not idx:
104*4882a593Smuzhiyun-            output.write('\t')
105*4882a593Smuzhiyun-        output.write('0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x, ' % (ord(v1), ord(v2), ord(v3), ord(v4), ord(v5), ord(v6), ord(v7), ord(v8)))
106*4882a593Smuzhiyun+            output.write(u'\t')
107*4882a593Smuzhiyun+        output.write(u'0x{:016x}ULL, '.format(vword))
108*4882a593Smuzhiyun         idx += 1
109*4882a593Smuzhiyun         if idx == 2:
110*4882a593Smuzhiyun             idx = 0
111*4882a593Smuzhiyun-            output.write('\n')
112*4882a593Smuzhiyun+            output.write(u'\n')
113*4882a593Smuzhiyun     if idx:
114*4882a593Smuzhiyun-        output.write('\n')
115*4882a593Smuzhiyun-    output.write('};\n\n')
116*4882a593Smuzhiyun+        output.write(u'\n')
117*4882a593Smuzhiyun+    output.write(u'};\n\n')
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun def print_ssl_32(output, name, val):
120*4882a593Smuzhiyun-    while val[0] == '\0':
121*4882a593Smuzhiyun-        val = val[1:]
122*4882a593Smuzhiyun-    while len(val) % 4:
123*4882a593Smuzhiyun-        val = '\0' + val
124*4882a593Smuzhiyun-    vnew = []
125*4882a593Smuzhiyun-    while len(val):
126*4882a593Smuzhiyun-        vnew.append((val[0], val[1], val[2], val[3], ))
127*4882a593Smuzhiyun-        val = val[4:]
128*4882a593Smuzhiyun-    vnew.reverse()
129*4882a593Smuzhiyun-    output.write('static BN_ULONG %s[%d] = {\n' % (name, len(vnew)))
130*4882a593Smuzhiyun+    # OpenSSL expects 32-bit words given least-significant-word first.
131*4882a593Smuzhiyun+    vwords = bitwise_collect(val, 32)
132*4882a593Smuzhiyun+
133*4882a593Smuzhiyun+    output.write(u'static BN_ULONG {}[] = {{\n'.format(name))
134*4882a593Smuzhiyun     idx = 0
135*4882a593Smuzhiyun-    for v1, v2, v3, v4 in vnew:
136*4882a593Smuzhiyun+    for vword in vwords:
137*4882a593Smuzhiyun         if not idx:
138*4882a593Smuzhiyun-            output.write('\t')
139*4882a593Smuzhiyun-        output.write('0x%.2x%.2x%.2x%.2x, ' % (ord(v1), ord(v2), ord(v3), ord(v4)))
140*4882a593Smuzhiyun+            output.write(u'\t')
141*4882a593Smuzhiyun+        output.write(u'0x{:08x}, '.format(vword))
142*4882a593Smuzhiyun         idx += 1
143*4882a593Smuzhiyun         if idx == 4:
144*4882a593Smuzhiyun             idx = 0
145*4882a593Smuzhiyun-            output.write('\n')
146*4882a593Smuzhiyun+            output.write(u'\n')
147*4882a593Smuzhiyun     if idx:
148*4882a593Smuzhiyun-        output.write('\n')
149*4882a593Smuzhiyun-    output.write('};\n\n')
150*4882a593Smuzhiyun+        output.write(u'\n')
151*4882a593Smuzhiyun+    output.write(u'};\n\n')
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun def print_ssl(output, name, val):
154*4882a593Smuzhiyun+
155*4882a593Smuzhiyun+    output.write(u'#include <stdint.h>\n')
156*4882a593Smuzhiyun+    output.write(u'#include <openssl/bn.h>\n')
157*4882a593Smuzhiyun+
158*4882a593Smuzhiyun     import struct
159*4882a593Smuzhiyun-    output.write('#include <stdint.h>\n')
160*4882a593Smuzhiyun     if len(struct.pack('@L', 0)) == 8:
161*4882a593Smuzhiyun         return print_ssl_64(output, name, val)
162*4882a593Smuzhiyun     else:
163*4882a593Smuzhiyun         return print_ssl_32(output, name, val)
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun def print_ssl_keys(output, n):
166*4882a593Smuzhiyun-    output.write(r'''
167*4882a593Smuzhiyun+    output.write(u'''
168*4882a593Smuzhiyun struct pubkey {
169*4882a593Smuzhiyun 	struct bignum_st e, n;
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun-#define KEY(data) {				\
173*4882a593Smuzhiyun-	.d = data,				\
174*4882a593Smuzhiyun-	.top = sizeof(data)/sizeof(data[0]),	\
175*4882a593Smuzhiyun+#define KEY(data) {                          \\
176*4882a593Smuzhiyun+	.d = data,                           \\
177*4882a593Smuzhiyun+	.top = sizeof(data)/sizeof(data[0]), \\
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun-#define KEYS(e,n)	{ KEY(e), KEY(n), }
181*4882a593Smuzhiyun+#define KEYS(e,n)    { KEY(e), KEY(n), }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun static struct pubkey keys[] = {
184*4882a593Smuzhiyun ''')
185*4882a593Smuzhiyun     for n in xrange(n + 1):
186*4882a593Smuzhiyun-        output.write('	KEYS(e_%d, n_%d),\n' % (n, n))
187*4882a593Smuzhiyun-    output.write('};\n')
188*4882a593Smuzhiyun+        output.write(u'	KEYS(e_{0}, n_{0}),\n'.format(n))
189*4882a593Smuzhiyun+    output.write(u'};\n')
190*4882a593Smuzhiyun     pass
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun def print_gcrypt(output, name, val):
193*4882a593Smuzhiyun-    output.write('#include <stdint.h>\n')
194*4882a593Smuzhiyun-    while val[0] == '\0':
195*4882a593Smuzhiyun-        val = val[1:]
196*4882a593Smuzhiyun-    output.write('static const uint8_t %s[%d] = {\n' % (name, len(val)))
197*4882a593Smuzhiyun+    # gcrypt expects 8-bit words most-significant-word first
198*4882a593Smuzhiyun+    vwords = bitwise_collect(val, 8)
199*4882a593Smuzhiyun+    vwords.reverse()
200*4882a593Smuzhiyun+
201*4882a593Smuzhiyun+    output.write(u'#include <stdint.h>\n')
202*4882a593Smuzhiyun+    output.write(u'static const uint8_t %s[%d] = {\n' % (name, len(vwords)))
203*4882a593Smuzhiyun     idx = 0
204*4882a593Smuzhiyun-    for v in val:
205*4882a593Smuzhiyun+    for vword in vwords:
206*4882a593Smuzhiyun         if not idx:
207*4882a593Smuzhiyun-            output.write('\t')
208*4882a593Smuzhiyun-        output.write('0x%.2x, ' % ord(v))
209*4882a593Smuzhiyun+            output.write(u'\t')
210*4882a593Smuzhiyun+        output.write(u'0x{:02x}, '.format(vword))
211*4882a593Smuzhiyun         idx += 1
212*4882a593Smuzhiyun         if idx == 8:
213*4882a593Smuzhiyun             idx = 0
214*4882a593Smuzhiyun-            output.write('\n')
215*4882a593Smuzhiyun+            output.write(u'\n')
216*4882a593Smuzhiyun     if idx:
217*4882a593Smuzhiyun-        output.write('\n')
218*4882a593Smuzhiyun-    output.write('};\n\n')
219*4882a593Smuzhiyun+        output.write(u'\n')
220*4882a593Smuzhiyun+    output.write(u'};\n\n')
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun def print_gcrypt_keys(output, n):
223*4882a593Smuzhiyun-    output.write(r'''
224*4882a593Smuzhiyun+    output.write(u'''
225*4882a593Smuzhiyun struct key_params {
226*4882a593Smuzhiyun 	const uint8_t *e, *n;
227*4882a593Smuzhiyun 	uint32_t len_e, len_n;
228*4882a593Smuzhiyun };
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun-#define KEYS(_e, _n) {			\
231*4882a593Smuzhiyun-	.e = _e, .len_e = sizeof(_e),	\
232*4882a593Smuzhiyun-	.n = _n, .len_n = sizeof(_n),	\
233*4882a593Smuzhiyun+#define KEYS(_e, _n) {                \\
234*4882a593Smuzhiyun+	.e = _e, .len_e = sizeof(_e), \\
235*4882a593Smuzhiyun+	.n = _n, .len_n = sizeof(_n), \\
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun static const struct key_params __attribute__ ((unused)) keys[] = {
239*4882a593Smuzhiyun ''')
240*4882a593Smuzhiyun-    for n in xrange(n + 1):
241*4882a593Smuzhiyun-        output.write('	KEYS(e_%d, n_%d),\n' % (n, n))
242*4882a593Smuzhiyun-    output.write('};\n')
243*4882a593Smuzhiyun-
244*4882a593Smuzhiyun+    for n in range(n + 1):
245*4882a593Smuzhiyun+        output.write(u'	KEYS(e_{0}, n_{0}),\n'.format(n))
246*4882a593Smuzhiyun+    output.write(u'};\n')
247*4882a593Smuzhiyun+
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun modes = {
250*4882a593Smuzhiyun     '--ssl': (print_ssl, print_ssl_keys),
251*4882a593Smuzhiyun@@ -135,21 +137,21 @@ except IndexError:
252*4882a593Smuzhiyun     mode = None
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if not mode in modes:
255*4882a593Smuzhiyun-    print 'Usage: %s [%s] input-file... output-file' % (sys.argv[0], '|'.join(modes.keys()))
256*4882a593Smuzhiyun+    print('Usage: {} [{}] input-file... output-file'.format(sys.argv[0], '|'.join(modes.keys())))
257*4882a593Smuzhiyun     sys.exit(2)
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun-output = open(outfile, 'w')
260*4882a593Smuzhiyun+output = io.open(outfile, 'w')
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun # load key
263*4882a593Smuzhiyun idx = 0
264*4882a593Smuzhiyun for f in files:
265*4882a593Smuzhiyun-    try:
266*4882a593Smuzhiyun-        key = RSA.load_pub_key(f)
267*4882a593Smuzhiyun-    except RSA.RSAError:
268*4882a593Smuzhiyun-        key = RSA.load_key(f)
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun-    modes[mode][0](output, 'e_%d' % idx, key.e[4:])
271*4882a593Smuzhiyun-    modes[mode][0](output, 'n_%d' % idx, key.n[4:])
272*4882a593Smuzhiyun+    key_contents = io.open(f, 'rb').read()
273*4882a593Smuzhiyun+    key = RSA.importKey(key_contents)
274*4882a593Smuzhiyun+
275*4882a593Smuzhiyun+    modes[mode][0](output, 'e_{}'.format(idx), key.e)
276*4882a593Smuzhiyun+    modes[mode][0](output, 'n_{}'.format(idx), key.n)
277*4882a593Smuzhiyun+
278*4882a593Smuzhiyun     idx += 1
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun modes[mode][1](output, idx - 1)
281*4882a593Smuzhiyun--
282*4882a593Smuzhiyun2.25.3
283*4882a593Smuzhiyun
284