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