pkcs1_v2.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # https://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. """Functions for PKCS#1 version 2 encryption and signing
  17. This module implements certain functionality from PKCS#1 version 2. Main
  18. documentation is RFC 2437: https://tools.ietf.org/html/rfc2437
  19. """
  20. from rsa._compat import range
  21. from rsa import (
  22. common,
  23. pkcs1,
  24. transform,
  25. )
  26. def mgf1(seed, length, hasher='SHA-1'):
  27. """
  28. MGF1 is a Mask Generation Function based on a hash function.
  29. A mask generation function takes an octet string of variable length and a
  30. desired output length as input, and outputs an octet string of the desired
  31. length. The plaintext-awareness of RSAES-OAEP relies on the random nature of
  32. the output of the mask generation function, which in turn relies on the
  33. random nature of the underlying hash.
  34. :param bytes seed: seed from which mask is generated, an octet string
  35. :param int length: intended length in octets of the mask, at most 2^32(hLen)
  36. :param str hasher: hash function (hLen denotes the length in octets of the hash
  37. function output)
  38. :return: mask, an octet string of length `length`
  39. :rtype: bytes
  40. :raise OverflowError: when `length` is too large for the specified `hasher`
  41. :raise ValueError: when specified `hasher` is invalid
  42. """
  43. try:
  44. hash_length = pkcs1.HASH_METHODS[hasher]().digest_size
  45. except KeyError:
  46. raise ValueError(
  47. 'Invalid `hasher` specified. Please select one of: {hash_list}'.format(
  48. hash_list=', '.join(sorted(pkcs1.HASH_METHODS.keys()))
  49. )
  50. )
  51. # If l > 2^32(hLen), output "mask too long" and stop.
  52. if length > (2**32 * hash_length):
  53. raise OverflowError(
  54. "Desired length should be at most 2**32 times the hasher's output "
  55. "length ({hash_length} for {hasher} function)".format(
  56. hash_length=hash_length,
  57. hasher=hasher,
  58. )
  59. )
  60. # Looping `counter` from 0 to ceil(l / hLen)-1, build `output` based on the
  61. # hashes formed by (`seed` + C), being `C` an octet string of length 4
  62. # generated by converting `counter` with the primitive I2OSP
  63. output = b''.join(
  64. pkcs1.compute_hash(
  65. seed + transform.int2bytes(counter, fill_size=4),
  66. method_name=hasher,
  67. )
  68. for counter in range(common.ceil_div(length, hash_length) + 1)
  69. )
  70. # Output the leading `length` octets of `output` as the octet string mask.
  71. return output[:length]
  72. __all__ = [
  73. 'mgf1',
  74. ]
  75. if __name__ == '__main__':
  76. print('Running doctests 1000x or until failure')
  77. import doctest
  78. for count in range(1000):
  79. (failures, tests) = doctest.testmod()
  80. if failures:
  81. break
  82. if count % 100 == 0 and count:
  83. print('%i times' % count)
  84. print('Doctests done')