Example #1
0
    def __init__(self, name, copy_from=None):
        self.ctx = ffi.NULL
        self.name = name
        digest_type = self.digest_type_by_name()
        self.digest_size = lib.EVP_MD_size(digest_type)

        # Allocate a lock for each HASH object.
        # An optimization would be to not release the GIL on small requests,
        # and use a custom lock only when needed.
        self.lock = Lock()

        ctx = lib.Cryptography_EVP_MD_CTX_new()
        if ctx == ffi.NULL:
            raise MemoryError
        ctx = ffi.gc(ctx, lib.Cryptography_EVP_MD_CTX_free)

        try:
            if copy_from is not None:
                # cpython uses EVP_MD_CTX_copy(...)
                if not lib.EVP_MD_CTX_copy_ex(ctx, copy_from):
                    raise ValueError
            else:
                # cpython uses EVP_DigestInit
                lib.EVP_DigestInit_ex(ctx, digest_type, ffi.NULL)
            self.ctx = ctx
        except:
            # no need to gc ctx! 
            raise
Example #2
0
 def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None):
     if not isinstance(hash_name, str):
         raise TypeError("expected 'str' for name, but got %s" % type(hash_name))
     c_name = _str_to_ffi_buffer(hash_name)
     digest = lib.EVP_get_digestbyname(c_name)
     if digest == ffi.NULL:
         raise ValueError("unsupported hash type")
     if dklen is None:
         dklen = lib.EVP_MD_size(digest)
     if dklen < 1:
         raise ValueError("key length must be greater than 0.")
     if dklen >= sys.maxsize:
         raise OverflowError("key length is too great.")
     if iterations < 1:
         raise ValueError("iteration value must be greater than 0.")
     if iterations >= sys.maxsize:
         raise OverflowError("iteration value is too great.")
     buf = ffi.new("unsigned char[]", dklen)
     c_password = ffi.from_buffer(bytes(password))
     c_salt = ffi.from_buffer(bytes(salt))
     r = lib.PKCS5_PBKDF2_HMAC(c_password, len(c_password),
             ffi.cast("unsigned char*",c_salt), len(c_salt),
             iterations, digest, dklen, buf)
     if r == 0:
         raise ValueError
     return _bytes_with_len(buf, dklen)