您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

155 行
5.3 KiB

  1. # This file is dual licensed under the terms of the Apache License, Version
  2. # 2.0, and the BSD License. See the LICENSE file in the root of this repository
  3. # for complete details.
  4. from __future__ import absolute_import, division, print_function
  5. import struct
  6. from cryptography.hazmat.primitives.ciphers import Cipher
  7. from cryptography.hazmat.primitives.ciphers.algorithms import AES
  8. from cryptography.hazmat.primitives.ciphers.modes import ECB
  9. from cryptography.hazmat.primitives.constant_time import bytes_eq
  10. def _wrap_core(wrapping_key, a, r, backend):
  11. # RFC 3394 Key Wrap - 2.2.1 (index method)
  12. encryptor = Cipher(AES(wrapping_key), ECB(), backend).encryptor()
  13. n = len(r)
  14. for j in range(6):
  15. for i in range(n):
  16. # every encryption operation is a discrete 16 byte chunk (because
  17. # AES has a 128-bit block size) and since we're using ECB it is
  18. # safe to reuse the encryptor for the entire operation
  19. b = encryptor.update(a + r[i])
  20. # pack/unpack are safe as these are always 64-bit chunks
  21. a = struct.pack(
  22. ">Q", struct.unpack(">Q", b[:8])[0] ^ ((n * j) + i + 1)
  23. )
  24. r[i] = b[-8:]
  25. assert encryptor.finalize() == b""
  26. return a + b"".join(r)
  27. def aes_key_wrap(wrapping_key, key_to_wrap, backend):
  28. if len(wrapping_key) not in [16, 24, 32]:
  29. raise ValueError("The wrapping key must be a valid AES key length")
  30. if len(key_to_wrap) < 16:
  31. raise ValueError("The key to wrap must be at least 16 bytes")
  32. if len(key_to_wrap) % 8 != 0:
  33. raise ValueError("The key to wrap must be a multiple of 8 bytes")
  34. a = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"
  35. r = [key_to_wrap[i:i + 8] for i in range(0, len(key_to_wrap), 8)]
  36. return _wrap_core(wrapping_key, a, r, backend)
  37. def _unwrap_core(wrapping_key, a, r, backend):
  38. # Implement RFC 3394 Key Unwrap - 2.2.2 (index method)
  39. decryptor = Cipher(AES(wrapping_key), ECB(), backend).decryptor()
  40. n = len(r)
  41. for j in reversed(range(6)):
  42. for i in reversed(range(n)):
  43. # pack/unpack are safe as these are always 64-bit chunks
  44. atr = struct.pack(
  45. ">Q", struct.unpack(">Q", a)[0] ^ ((n * j) + i + 1)
  46. ) + r[i]
  47. # every decryption operation is a discrete 16 byte chunk so
  48. # it is safe to reuse the decryptor for the entire operation
  49. b = decryptor.update(atr)
  50. a = b[:8]
  51. r[i] = b[-8:]
  52. assert decryptor.finalize() == b""
  53. return a, r
  54. def aes_key_wrap_with_padding(wrapping_key, key_to_wrap, backend):
  55. if len(wrapping_key) not in [16, 24, 32]:
  56. raise ValueError("The wrapping key must be a valid AES key length")
  57. aiv = b"\xA6\x59\x59\xA6" + struct.pack(">i", len(key_to_wrap))
  58. # pad the key to wrap if necessary
  59. pad = (8 - (len(key_to_wrap) % 8)) % 8
  60. key_to_wrap = key_to_wrap + b"\x00" * pad
  61. if len(key_to_wrap) == 8:
  62. # RFC 5649 - 4.1 - exactly 8 octets after padding
  63. encryptor = Cipher(AES(wrapping_key), ECB(), backend).encryptor()
  64. b = encryptor.update(aiv + key_to_wrap)
  65. assert encryptor.finalize() == b""
  66. return b
  67. else:
  68. r = [key_to_wrap[i:i + 8] for i in range(0, len(key_to_wrap), 8)]
  69. return _wrap_core(wrapping_key, aiv, r, backend)
  70. def aes_key_unwrap_with_padding(wrapping_key, wrapped_key, backend):
  71. if len(wrapped_key) < 16:
  72. raise InvalidUnwrap("Must be at least 16 bytes")
  73. if len(wrapping_key) not in [16, 24, 32]:
  74. raise ValueError("The wrapping key must be a valid AES key length")
  75. if len(wrapped_key) == 16:
  76. # RFC 5649 - 4.2 - exactly two 64-bit blocks
  77. decryptor = Cipher(AES(wrapping_key), ECB(), backend).decryptor()
  78. b = decryptor.update(wrapped_key)
  79. assert decryptor.finalize() == b""
  80. a = b[:8]
  81. data = b[8:]
  82. n = 1
  83. else:
  84. r = [wrapped_key[i:i + 8] for i in range(0, len(wrapped_key), 8)]
  85. encrypted_aiv = r.pop(0)
  86. n = len(r)
  87. a, r = _unwrap_core(wrapping_key, encrypted_aiv, r, backend)
  88. data = b"".join(r)
  89. # 1) Check that MSB(32,A) = A65959A6.
  90. # 2) Check that 8*(n-1) < LSB(32,A) <= 8*n. If so, let
  91. # MLI = LSB(32,A).
  92. # 3) Let b = (8*n)-MLI, and then check that the rightmost b octets of
  93. # the output data are zero.
  94. (mli,) = struct.unpack(">I", a[4:])
  95. b = (8 * n) - mli
  96. if (
  97. not bytes_eq(a[:4], b"\xa6\x59\x59\xa6") or not
  98. 8 * (n - 1) < mli <= 8 * n or (
  99. b != 0 and not bytes_eq(data[-b:], b"\x00" * b)
  100. )
  101. ):
  102. raise InvalidUnwrap()
  103. if b == 0:
  104. return data
  105. else:
  106. return data[:-b]
  107. def aes_key_unwrap(wrapping_key, wrapped_key, backend):
  108. if len(wrapped_key) < 24:
  109. raise InvalidUnwrap("Must be at least 24 bytes")
  110. if len(wrapped_key) % 8 != 0:
  111. raise InvalidUnwrap("The wrapped key must be a multiple of 8 bytes")
  112. if len(wrapping_key) not in [16, 24, 32]:
  113. raise ValueError("The wrapping key must be a valid AES key length")
  114. aiv = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"
  115. r = [wrapped_key[i:i + 8] for i in range(0, len(wrapped_key), 8)]
  116. a = r.pop(0)
  117. a, r = _unwrap_core(wrapping_key, a, r, backend)
  118. if not bytes_eq(a, aiv):
  119. raise InvalidUnwrap()
  120. return b"".join(r)
  121. class InvalidUnwrap(Exception):
  122. pass