Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(852)

Side by Side Diff: third_party/google-endpoints/jwkest/aes_key_wrap.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 """
2 Key wrapping and unwrapping as defined in RFC 3394.
3 Also a padding mechanism that was used in openssl at one time.
4 The purpose of this algorithm is to encrypt a key multiple times to add an
5 extra layer of security.
6
7 Personally, I wouldn't recommend using this for most applications.
8 Just use AES/mode CTR to encrypt your keys, the same as you would any other
9 data.
10 The time to use this code is when you need compatibility with another system
11 that implements the RFC.
12 (For example, these functions are compatible with the openssl functions of
13 the same name.)
14
15 Performance should be reasonable, since the heavy lifting is all done in
16 PyCrypto's AES.
17 """
18 from __future__ import division
19
20 try:
21 from builtins import hex
22 from builtins import range
23 except ImportError:
24 pass
25 import struct
26 from Crypto.Cipher import AES
27
28 QUAD = struct.Struct('>Q')
29
30
31 def aes_unwrap_key_and_iv(kek, wrapped):
32 n = (len(wrapped) // 8) - 1
33 #NOTE: R[0] is never accessed, left in for consistency with RFC indices
34 r = [None] + [wrapped[i * 8:i * 8 + 8] for i in range(1, n + 1)]
35 a = QUAD.unpack(wrapped[:8])[0]
36 decrypt = AES.new(kek).decrypt
37 for j in range(5, -1, -1): #counting down
38 for i in range(n, 0, -1): #(n, n-1, ..., 1)
39 ciphertext = QUAD.pack(a ^ (n * j + i)) + r[i]
40 B = decrypt(ciphertext)
41 a = QUAD.unpack(B[:8])[0]
42 r[i] = B[8:]
43 return b"".join(r[1:]), a
44
45
46 def aes_unwrap_key(kek, wrapped, iv=0xa6a6a6a6a6a6a6a6):
47 key, key_iv = aes_unwrap_key_and_iv(kek, wrapped)
48 if key_iv != iv:
49 raise ValueError(
50 "Integrity Check Failed: " + hex(key_iv) + " (expected " + hex(
51 iv) + ")")
52 return key
53
54
55 def aes_unwrap_key_withpad(kek, wrapped):
56 key, key_iv = aes_unwrap_key_and_iv(kek, wrapped)
57 key_iv = "{0:016X}".format(key_iv)
58 if key_iv[:8] != "A65959A6":
59 raise ValueError(
60 "Integrity Check Failed: " + key_iv[:8] + " (expected A65959A6)")
61 key_len = int(key_iv[8:], 16)
62 return key[:key_len]
63
64
65 def aes_wrap_key(kek, plaintext, iv=0xa6a6a6a6a6a6a6a6):
66 n = len(plaintext) // 8
67 r = [None] + [plaintext[i * 8:i * 8 + 8] for i in range(0, n)]
68 a = iv
69 encrypt = AES.new(kek).encrypt
70 for j in range(6):
71 for i in range(1, n + 1):
72 b = encrypt(QUAD.pack(a) + r[i])
73 a = QUAD.unpack(b[:8])[0] ^ (n * j + i)
74 r[i] = b[8:]
75 return QUAD.pack(a) + b''.join(r[1:])
76
77
78 def aes_wrap_key_withpad(kek, plaintext):
79 iv = 0xA65959A600000000 + len(plaintext)
80 plaintext += "\0" * (8 - len(plaintext) % 8)
81 return aes_wrap_key(kek, plaintext, iv)
82
83
84 def test():
85 #test vector from RFC 3394
86 import binascii
87
88 KEK = binascii.unhexlify("000102030405060708090A0B0C0D0E0F")
89 CIPHER = binascii.unhexlify(
90 "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5")
91 PLAIN = binascii.unhexlify("00112233445566778899AABBCCDDEEFF")
92 assert aes_unwrap_key(KEK, CIPHER) == PLAIN
93 assert aes_wrap_key(KEK, PLAIN) == CIPHER
OLDNEW
« no previous file with comments | « third_party/google-endpoints/jwkest/aes_gcm.py ('k') | third_party/google-endpoints/jwkest/curves.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698