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

Unified Diff: third_party/google-endpoints/jwkest/aes_key_wrap.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/google-endpoints/jwkest/aes_key_wrap.py
diff --git a/third_party/google-endpoints/jwkest/aes_key_wrap.py b/third_party/google-endpoints/jwkest/aes_key_wrap.py
new file mode 100644
index 0000000000000000000000000000000000000000..037f0fb0813c6e3b664dcae97fd5c059c2f5bce7
--- /dev/null
+++ b/third_party/google-endpoints/jwkest/aes_key_wrap.py
@@ -0,0 +1,93 @@
+"""
+Key wrapping and unwrapping as defined in RFC 3394.
+Also a padding mechanism that was used in openssl at one time.
+The purpose of this algorithm is to encrypt a key multiple times to add an
+extra layer of security.
+
+Personally, I wouldn't recommend using this for most applications.
+Just use AES/mode CTR to encrypt your keys, the same as you would any other
+data.
+The time to use this code is when you need compatibility with another system
+that implements the RFC.
+(For example, these functions are compatible with the openssl functions of
+the same name.)
+
+Performance should be reasonable, since the heavy lifting is all done in
+PyCrypto's AES.
+"""
+from __future__ import division
+
+try:
+ from builtins import hex
+ from builtins import range
+except ImportError:
+ pass
+import struct
+from Crypto.Cipher import AES
+
+QUAD = struct.Struct('>Q')
+
+
+def aes_unwrap_key_and_iv(kek, wrapped):
+ n = (len(wrapped) // 8) - 1
+ #NOTE: R[0] is never accessed, left in for consistency with RFC indices
+ r = [None] + [wrapped[i * 8:i * 8 + 8] for i in range(1, n + 1)]
+ a = QUAD.unpack(wrapped[:8])[0]
+ decrypt = AES.new(kek).decrypt
+ for j in range(5, -1, -1): #counting down
+ for i in range(n, 0, -1): #(n, n-1, ..., 1)
+ ciphertext = QUAD.pack(a ^ (n * j + i)) + r[i]
+ B = decrypt(ciphertext)
+ a = QUAD.unpack(B[:8])[0]
+ r[i] = B[8:]
+ return b"".join(r[1:]), a
+
+
+def aes_unwrap_key(kek, wrapped, iv=0xa6a6a6a6a6a6a6a6):
+ key, key_iv = aes_unwrap_key_and_iv(kek, wrapped)
+ if key_iv != iv:
+ raise ValueError(
+ "Integrity Check Failed: " + hex(key_iv) + " (expected " + hex(
+ iv) + ")")
+ return key
+
+
+def aes_unwrap_key_withpad(kek, wrapped):
+ key, key_iv = aes_unwrap_key_and_iv(kek, wrapped)
+ key_iv = "{0:016X}".format(key_iv)
+ if key_iv[:8] != "A65959A6":
+ raise ValueError(
+ "Integrity Check Failed: " + key_iv[:8] + " (expected A65959A6)")
+ key_len = int(key_iv[8:], 16)
+ return key[:key_len]
+
+
+def aes_wrap_key(kek, plaintext, iv=0xa6a6a6a6a6a6a6a6):
+ n = len(plaintext) // 8
+ r = [None] + [plaintext[i * 8:i * 8 + 8] for i in range(0, n)]
+ a = iv
+ encrypt = AES.new(kek).encrypt
+ for j in range(6):
+ for i in range(1, n + 1):
+ b = encrypt(QUAD.pack(a) + r[i])
+ a = QUAD.unpack(b[:8])[0] ^ (n * j + i)
+ r[i] = b[8:]
+ return QUAD.pack(a) + b''.join(r[1:])
+
+
+def aes_wrap_key_withpad(kek, plaintext):
+ iv = 0xA65959A600000000 + len(plaintext)
+ plaintext += "\0" * (8 - len(plaintext) % 8)
+ return aes_wrap_key(kek, plaintext, iv)
+
+
+def test():
+ #test vector from RFC 3394
+ import binascii
+
+ KEK = binascii.unhexlify("000102030405060708090A0B0C0D0E0F")
+ CIPHER = binascii.unhexlify(
+ "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5")
+ PLAIN = binascii.unhexlify("00112233445566778899AABBCCDDEEFF")
+ assert aes_unwrap_key(KEK, CIPHER) == PLAIN
+ assert aes_wrap_key(KEK, PLAIN) == CIPHER
« 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