crypto.pyx 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. """A thin OpenSSL wrapper
  2. This could be replaced by PyCrypto or something similar when the performance
  3. of their PBKDF2 implementation is comparable to the OpenSSL version.
  4. """
  5. from libc.stdlib cimport malloc, free
  6. API_VERSION = 2
  7. AES_CTR_MODE = 1
  8. AES_GCM_MODE = 2
  9. MAC_SIZE = 16 # bytes; 128 bits is the maximum allowed value. see "hack" below.
  10. IV_SIZE = 16 # bytes; 128 bits
  11. cdef extern from "openssl/rand.h":
  12. int RAND_bytes(unsigned char *buf, int num)
  13. cdef extern from "openssl/evp.h":
  14. ctypedef struct EVP_MD:
  15. pass
  16. ctypedef struct EVP_CIPHER:
  17. pass
  18. ctypedef struct EVP_CIPHER_CTX:
  19. unsigned char *iv
  20. pass
  21. ctypedef struct ENGINE:
  22. pass
  23. const EVP_MD *EVP_sha256()
  24. const EVP_CIPHER *EVP_aes_256_ctr()
  25. const EVP_CIPHER *EVP_aes_256_gcm()
  26. void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a)
  27. void EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a)
  28. int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
  29. const unsigned char *key, const unsigned char *iv)
  30. int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
  31. const unsigned char *key, const unsigned char *iv)
  32. int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
  33. const unsigned char *in_, int inl)
  34. int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
  35. const unsigned char *in_, int inl)
  36. int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
  37. int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
  38. int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, unsigned char *ptr)
  39. int PKCS5_PBKDF2_HMAC(const char *password, int passwordlen,
  40. const unsigned char *salt, int saltlen, int iter,
  41. const EVP_MD *digest,
  42. int keylen, unsigned char *out)
  43. int EVP_CTRL_GCM_GET_TAG
  44. int EVP_CTRL_GCM_SET_TAG
  45. int EVP_CTRL_GCM_SET_IVLEN
  46. import struct
  47. _int = struct.Struct('>I')
  48. _2long = struct.Struct('>QQ')
  49. bytes_to_int = lambda x, offset=0: _int.unpack_from(x, offset)[0]
  50. def bytes16_to_int(b, offset=0):
  51. h, l = _2long.unpack_from(b, offset)
  52. return (h << 64) + l
  53. def int_to_bytes16(i):
  54. max_uint64 = 0xffffffffffffffff
  55. l = i & max_uint64
  56. h = (i >> 64) & max_uint64
  57. return _2long.pack(h, l)
  58. def num_aes_blocks(length):
  59. """Return the number of AES blocks required to encrypt/decrypt *length* bytes of data.
  60. Note: this is only correct for modes without padding, like AES-CTR.
  61. """
  62. return (length + 15) // 16
  63. def increment_iv(iv, amount):
  64. """
  65. increment the given IV considering that <amount> bytes of data was
  66. encrypted based on it. In CTR / GCM mode, the IV is just a counter and
  67. must never repeat.
  68. :param iv: current IV, 16 bytes (128 bit)
  69. :param amount: amount of data (in bytes) that was encrypted
  70. :return: new IV, 16 bytes (128 bit)
  71. """
  72. iv = bytes16_to_int(iv)
  73. iv += num_aes_blocks(amount)
  74. iv = int_to_bytes16(iv)
  75. return iv
  76. def pbkdf2_sha256(password, salt, iterations, size):
  77. """Password based key derivation function 2 (RFC2898)
  78. """
  79. cdef unsigned char *key = <unsigned char *>malloc(size)
  80. if not key:
  81. raise MemoryError
  82. try:
  83. rv = PKCS5_PBKDF2_HMAC(password, len(password), salt, len(salt), iterations, EVP_sha256(), size, key)
  84. if not rv:
  85. raise Exception('PKCS5_PBKDF2_HMAC failed')
  86. return key[:size]
  87. finally:
  88. free(key)
  89. def get_random_bytes(n):
  90. """Return n cryptographically strong pseudo-random bytes
  91. """
  92. cdef unsigned char *buf = <unsigned char *>malloc(n)
  93. if not buf:
  94. raise MemoryError
  95. try:
  96. if RAND_bytes(buf, n) < 1:
  97. raise Exception('RAND_bytes failed')
  98. return buf[:n]
  99. finally:
  100. free(buf)
  101. cdef class AES:
  102. """A thin wrapper around the OpenSSL EVP cipher API
  103. """
  104. cdef EVP_CIPHER_CTX ctx
  105. cdef int is_encrypt
  106. cdef int mode
  107. def __cinit__(self, mode, is_encrypt, key, iv=None):
  108. EVP_CIPHER_CTX_init(&self.ctx)
  109. self.mode = mode
  110. self.is_encrypt = is_encrypt
  111. # Set cipher type and mode
  112. if mode == AES_CTR_MODE:
  113. cipher_mode = EVP_aes_256_ctr()
  114. elif mode == AES_GCM_MODE:
  115. cipher_mode = EVP_aes_256_gcm()
  116. else:
  117. raise Exception('unknown mode')
  118. if self.is_encrypt:
  119. if not EVP_EncryptInit_ex(&self.ctx, cipher_mode, NULL, NULL, NULL):
  120. raise Exception('EVP_EncryptInit_ex failed')
  121. else: # decrypt
  122. if not EVP_DecryptInit_ex(&self.ctx, cipher_mode, NULL, NULL, NULL):
  123. raise Exception('EVP_DecryptInit_ex failed')
  124. self.reset(key, iv)
  125. def __dealloc__(self):
  126. EVP_CIPHER_CTX_cleanup(&self.ctx)
  127. def reset(self, key=None, iv=None):
  128. cdef const unsigned char *key2 = NULL
  129. cdef const unsigned char *iv2 = NULL
  130. if key:
  131. key2 = key
  132. if iv:
  133. iv2 = iv
  134. if self.mode == AES_GCM_MODE:
  135. # Set IV length (bytes)
  136. if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_IVLEN, IV_SIZE, NULL):
  137. raise Exception('EVP_CIPHER_CTX_ctrl SET IVLEN failed')
  138. # Initialise key and IV
  139. if self.is_encrypt:
  140. if not EVP_EncryptInit_ex(&self.ctx, NULL, NULL, key2, iv2):
  141. raise Exception('EVP_EncryptInit_ex failed')
  142. else: # decrypt
  143. if not EVP_DecryptInit_ex(&self.ctx, NULL, NULL, key2, iv2):
  144. raise Exception('EVP_DecryptInit_ex failed')
  145. def add(self, aad):
  146. cdef int aadl = len(aad)
  147. cdef int outl
  148. if self.mode != AES_GCM_MODE:
  149. raise Exception('additional data only supported for AES GCM mode')
  150. # Zero or more calls to specify any AAD
  151. if self.is_encrypt:
  152. if not EVP_EncryptUpdate(&self.ctx, NULL, &outl, aad, aadl):
  153. raise Exception('EVP_EncryptUpdate failed')
  154. else: # decrypt
  155. if not EVP_DecryptUpdate(&self.ctx, NULL, &outl, aad, aadl):
  156. raise Exception('EVP_DecryptUpdate failed')
  157. def compute_mac_and_encrypt(self, data):
  158. cdef int inl = len(data)
  159. cdef int ctl = 0
  160. cdef int outl = 0
  161. # note: modes that use padding, need up to one extra AES block (16B)
  162. cdef unsigned char *out = <unsigned char *>malloc(inl+16)
  163. cdef unsigned char *mac = <unsigned char *>malloc(MAC_SIZE)
  164. if not out:
  165. raise MemoryError
  166. try:
  167. if not EVP_EncryptUpdate(&self.ctx, out, &outl, data, inl):
  168. raise Exception('EVP_EncryptUpdate failed')
  169. ctl = outl
  170. if not EVP_EncryptFinal_ex(&self.ctx, out+ctl, &outl):
  171. raise Exception('EVP_EncryptFinal failed')
  172. ctl += outl
  173. if self.mode == AES_GCM_MODE:
  174. # Get tag (mac) - only GCM mode. for CTR, the returned mac is undefined
  175. if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_GET_TAG, MAC_SIZE, mac):
  176. raise Exception('EVP_CIPHER_CTX_ctrl GET TAG failed')
  177. return (mac[:MAC_SIZE]), out[:ctl]
  178. finally:
  179. free(mac)
  180. free(out)
  181. def check_mac_and_decrypt(self, mac, data):
  182. cdef int inl = len(data)
  183. cdef int ptl = 0
  184. cdef int outl = 0
  185. # note: modes that use padding, need up to one extra AES block (16B).
  186. # This is what the openssl docs say. I am not sure this is correct,
  187. # but OTOH it will not cause any harm if our buffer is a little bigger.
  188. cdef unsigned char *out = <unsigned char *>malloc(inl+16)
  189. if not out:
  190. raise MemoryError
  191. try:
  192. if not EVP_DecryptUpdate(&self.ctx, out, &outl, data, inl):
  193. raise Exception('EVP_DecryptUpdate failed')
  194. ptl = outl
  195. if self.mode == AES_GCM_MODE:
  196. # Set expected tag (mac) value.
  197. if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_TAG, MAC_SIZE, mac):
  198. raise Exception('EVP_CIPHER_CTX_ctrl SET TAG failed')
  199. if EVP_DecryptFinal_ex(&self.ctx, out+ptl, &outl) <= 0:
  200. # for GCM mode, a failure here means corrupted / tampered tag (mac) or data
  201. raise Exception('EVP_DecryptFinal failed')
  202. ptl += outl
  203. return out[:ptl]
  204. finally:
  205. free(out)