crypto_generichash.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. # Copyright 2013 Donald Stufft and individual contributors
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from __future__ import absolute_import, division, print_function
  15. from six import integer_types
  16. from nacl import exceptions as exc
  17. from nacl._sodium import ffi, lib
  18. from nacl.exceptions import ensure
  19. crypto_generichash_BYTES = lib.crypto_generichash_blake2b_bytes()
  20. crypto_generichash_BYTES_MIN = lib.crypto_generichash_blake2b_bytes_min()
  21. crypto_generichash_BYTES_MAX = lib.crypto_generichash_blake2b_bytes_max()
  22. crypto_generichash_KEYBYTES = lib.crypto_generichash_blake2b_keybytes()
  23. crypto_generichash_KEYBYTES_MIN = lib.crypto_generichash_blake2b_keybytes_min()
  24. crypto_generichash_KEYBYTES_MAX = lib.crypto_generichash_blake2b_keybytes_max()
  25. crypto_generichash_SALTBYTES = lib.crypto_generichash_blake2b_saltbytes()
  26. crypto_generichash_PERSONALBYTES = \
  27. lib.crypto_generichash_blake2b_personalbytes()
  28. crypto_generichash_STATEBYTES = lib.crypto_generichash_statebytes()
  29. _OVERLONG = '{0} length greater than {1} bytes'
  30. _TOOBIG = '{0} greater than {1}'
  31. def _checkparams(digest_size, key, salt, person):
  32. """Check hash paramters"""
  33. ensure(isinstance(key, bytes),
  34. 'Key must be a bytes sequence',
  35. raising=exc.TypeError)
  36. ensure(isinstance(salt, bytes),
  37. 'Salt must be a bytes sequence',
  38. raising=exc.TypeError)
  39. ensure(isinstance(person, bytes),
  40. 'Person must be a bytes sequence',
  41. raising=exc.TypeError)
  42. ensure(isinstance(digest_size, integer_types),
  43. 'Digest size must be an integer number',
  44. raising=exc.TypeError)
  45. ensure(digest_size <= crypto_generichash_BYTES_MAX,
  46. _TOOBIG.format("Digest_size", crypto_generichash_BYTES_MAX),
  47. raising=exc.ValueError)
  48. ensure(len(key) <= crypto_generichash_KEYBYTES_MAX,
  49. _OVERLONG.format("Key", crypto_generichash_KEYBYTES_MAX),
  50. raising=exc.ValueError)
  51. ensure(len(salt) <= crypto_generichash_SALTBYTES,
  52. _OVERLONG.format("Salt", crypto_generichash_SALTBYTES),
  53. raising=exc.ValueError)
  54. ensure(len(person) <= crypto_generichash_PERSONALBYTES,
  55. _OVERLONG.format("Person", crypto_generichash_PERSONALBYTES),
  56. raising=exc.ValueError)
  57. def generichash_blake2b_salt_personal(data,
  58. digest_size=crypto_generichash_BYTES,
  59. key=b'', salt=b'', person=b''):
  60. """One shot hash interface
  61. :param data: the input data to the hash function
  62. :param digest_size: must be at most
  63. :py:data:`.crypto_generichash_BYTES_MAX`;
  64. the default digest size is
  65. :py:data:`.crypto_generichash_BYTES`
  66. :type digest_size: int
  67. :param key: must be at most
  68. :py:data:`.crypto_generichash_KEYBYTES_MAX` long
  69. :type key: bytes
  70. :param salt: must be at most
  71. :py:data:`.crypto_generichash_SALTBYTES` long;
  72. will be zero-padded if needed
  73. :type salt: bytes
  74. :param person: must be at most
  75. :py:data:`.crypto_generichash_PERSONALBYTES` long:
  76. will be zero-padded if needed
  77. :type person: bytes
  78. :return: digest_size long digest
  79. :rtype: bytes
  80. """
  81. _checkparams(digest_size, key, salt, person)
  82. ensure(isinstance(data, bytes),
  83. 'Input data must be a bytes sequence',
  84. raising=exc.TypeError)
  85. digest = ffi.new("unsigned char[]", digest_size)
  86. # both _salt and _personal must be zero-padded to the correct length
  87. _salt = ffi.new("unsigned char []", crypto_generichash_SALTBYTES)
  88. _person = ffi.new("unsigned char []", crypto_generichash_PERSONALBYTES)
  89. ffi.memmove(_salt, salt, len(salt))
  90. ffi.memmove(_person, person, len(person))
  91. rc = lib.crypto_generichash_blake2b_salt_personal(digest, digest_size,
  92. data, len(data),
  93. key, len(key),
  94. _salt, _person)
  95. ensure(rc == 0, 'Unexpected failure',
  96. raising=exc.RuntimeError)
  97. return ffi.buffer(digest, digest_size)[:]
  98. def generichash_blake2b_init(key=b'', salt=b'',
  99. person=b'',
  100. digest_size=crypto_generichash_BYTES):
  101. """
  102. Create a new initialized blake2b hash state
  103. :param key: must be at most
  104. :py:data:`.crypto_generichash_KEYBYTES_MAX` long
  105. :type key: bytes
  106. :param salt: must be at most
  107. :py:data:`.crypto_generichash_SALTBYTES` long;
  108. will be zero-padded if needed
  109. :type salt: bytes
  110. :param person: must be at most
  111. :py:data:`.crypto_generichash_PERSONALBYTES` long:
  112. will be zero-padded if needed
  113. :type person: bytes
  114. :param digest_size: must be at most
  115. :py:data:`.crypto_generichash_BYTES_MAX`;
  116. the default digest size is
  117. :py:data:`.crypto_generichash_BYTES`
  118. :type digest_size: int
  119. :return: an initizialized state buffer
  120. :rtype: bytes
  121. """
  122. _checkparams(digest_size, key, salt, person)
  123. statebuf = ffi.new("unsigned char[]", crypto_generichash_STATEBYTES)
  124. # both _salt and _personal must be zero-padded to the correct length
  125. _salt = ffi.new("unsigned char []", crypto_generichash_SALTBYTES)
  126. _person = ffi.new("unsigned char []", crypto_generichash_PERSONALBYTES)
  127. ffi.memmove(_salt, salt, len(salt))
  128. ffi.memmove(_person, person, len(person))
  129. rc = lib.crypto_generichash_blake2b_init_salt_personal(statebuf,
  130. key, len(key),
  131. digest_size,
  132. _salt, _person)
  133. ensure(rc == 0, 'Unexpected failure',
  134. raising=exc.RuntimeError)
  135. return statebuf
  136. def generichash_blake2b_update(statebuf, data):
  137. """Update the blake2b hash state
  138. :param statebuf: an initialized blake2b state buffer as returned from
  139. :py:func:`.crypto_generichash_blake2b_init`
  140. :type name: bytes
  141. :param data:
  142. :type data: bytes
  143. """
  144. ensure(isinstance(data, bytes),
  145. 'Input data must be a bytes sequence',
  146. raising=exc.TypeError)
  147. rc = lib.crypto_generichash_blake2b_update(statebuf, data, len(data))
  148. ensure(rc == 0, 'Unexpected failure',
  149. raising=exc.RuntimeError)
  150. def generichash_blake2b_final(statebuf, digest_size):
  151. """Finalize the blake2b hash state and return the digest.
  152. :param statebuf:
  153. :type statebuf: bytes
  154. :param digest_size:
  155. :type digest_size: int
  156. :return: the blake2 digest of the passed-in data stream
  157. :rtype: bytes
  158. """
  159. _digest = ffi.new("unsigned char[]", crypto_generichash_BYTES_MAX)
  160. rc = lib.crypto_generichash_blake2b_final(statebuf, _digest, digest_size)
  161. ensure(rc == 0, 'Unexpected failure',
  162. raising=exc.RuntimeError)
  163. return ffi.buffer(_digest, digest_size)[:]
  164. def generichash_blake2b_state_copy(statebuf):
  165. """Return a copy of the given blake2b hash state"""
  166. newstate = ffi.new("unsigned char[]", crypto_generichash_STATEBYTES)
  167. ffi.memmove(newstate, statebuf, crypto_generichash_STATEBYTES)
  168. return newstate