Example #1
0
    def seed(self, state, version=2, entropy=None):
        """Initialize internal state from hashable object.

        None or no argument seeds from current time or from an operating
        system specific randomness source if available.

        For version 2 (the default), all of the bits are used if *a *is a str,
        bytes, or bytearray.  For version 1, the hash() of *a* is used
        instead.

        If *a* is an int, all bits are used.
        """
        if state is None:
            if not api.RAND_status():
                while not api.RAND_status():
                    data = api.new('unsigned char[]', os.urandom(256))
                    api.RAND_seed(data, len(data))
            return
        elif isinstance(state, (str, bytes, bytearray)):
            if version > 1:
                if isinstance(state, str):
                    state = state.encode()
                data = api.new('unsigned char[]', state)
            else:
                state = hash(state)
                data = self._int_to_ubyte(state)
        else:
            data = self._int_to_ubyte(state)
        entropy = entropy if entropy is not None else 8 * len(data)
        api.RAND_add(data, len(data), entropy)
Example #2
0
 def set_cipher(self, enc):
     cipher = api.EVP_get_cipherbyname(self.algorithm)
     key = api.new('unsigned char[]', self.hexstr_to_numbers(self.key))
     iv = api.NULL
     if self.iv is not None:
         iv = api.new('unsigned char[]', self.hexstr_to_numbers(self.iv))
     api.BIO_set_cipher(self.filter, cipher, key, iv, 1 if enc else 0)
Example #3
0
    def __init__(self, key, msg=None, digestmod=None):
        """Create a new HMAC object.

        key:       key for the keyed hash object.
        msg:       Initial input for the hash, if provided.
        digestmod: A message digest name. *OR*
                   A module supporting PEP 247.  *OR*
                   A hashlib constructor returning a new hash object.

        If module or hashlib constuctor is passed as digestmod the '__name__'
        and 'args' attributes are searched to find a message digest name. If
        not provied the digestmod defaults to 'md5'.

        Note: key and msg must be a bytes objects.
        """
        if digestmod is None:
            self._md = api.EVP_md5()
        else:
            self._md = self._get_md(digestmod)
        ctx = api.new('HMAC_CTX*')
        self._key = api.new('char[]', key)
        api.HMAC_Init_ex(ctx, api.cast('void*', self._key),
                len(key), self._md, api.NULL)
        cleanup = lambda _: api.HMAC_CTX_cleanup(ctx)
        self._weakref = weakref.ref(self, cleanup)
        self._ctx = ctx
        if msg is not None:
            self.update(msg)
Example #4
0
    def initialise(self, key, ivector):
        """Initialise this cipher's state with a key and optional ivector

        The key must be a byte string of the same length as this cipher's
        key_len property. If the ivector is required, it must also be a byte
        string of ivector_len length. If not required it may be an empty string
        or None.
        """
        if self._ctx == api.NULL:
            raise ValueError("Cipher object failed to be initialised")
        if len(key) != self.key_len:
            msg = "Key must be {0} bytes. Received {1}".format(
                    self.key_len, len(key))
            raise ValueError(msg)
        c_key = api.new('char[]', key) if bool(key) else api.NULL
        if (len(ivector) if ivector is not None else 0) != self.ivector_len:
            msg = "IVector must be {0} bytes. Received{1}".format(
                    self.ivector_len, len(ivector))
            raise ValueError(msg)
        c_iv = api.new('char[]', ivector) if bool(ivector) else api.NULL
        if not api.EVP_CipherInit_ex(self._ctx,
                api.NULL, api.NULL, c_key, c_iv, -1):
            raise ValueError("Unable to initialise cipher")
        if self.digest is not None:
            self._hmac = hmac.HMAC(key, digestmod=self.digest)
        self._initialised = True
Example #5
0
 def test_long(self):
     data = api.new('char[]', self.data_long)
     buf = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE)
     size = api.new('unsigned int*')
     api.EVP_DigestUpdate(self.ctx, api.cast('void*', data), len(self.data_long))
     api.EVP_DigestFinal_ex(self.ctx, buf, size)
     hash_value = b''.join('{0:02x}'.format(v).encode() for v in islice(buf, size[0]))
     self.assertEqual(hash_value, self.hash_long)
Example #6
0
 def test_filter_write(self):
     self.set_cipher(enc=True)
     plaintext = api.new('unsigned char[]', self.hexstr_to_numbers(self.plaintext))
     ciphertext = api.new('unsigned char[]', self.hexstr_to_numbers(self.ciphertext))
     output = api.new('unsigned char[]', len(ciphertext))
     api.BIO_write(self.bio, plaintext, len(plaintext))
     api.BIO_flush(self.bio)
     api.BIO_read(self.sink, output, len(output))
     self.assertEqual(api.buffer(ciphertext)[:], api.buffer(output)[:])
Example #7
0
 def set_mode(self, enc):
     mode = 1 if enc else 0
     key = api.new('unsigned char[]', self.hexstr_to_numbers(self.key))
     iv = api.NULL
     if self.iv is not None:
         iv = api.new('unsigned char[]', self.hexstr_to_numbers(self.iv))
     api.EVP_CipherInit_ex(self.ctx, api.NULL, api.NULL, key, iv, mode)
     if not enc:
         api.EVP_CIPHER_CTX_set_padding(self.ctx, 0)
Example #8
0
 def test_filter_read(self):
     self.set_cipher(enc=False)
     plaintext = api.new('unsigned char[]', self.hexstr_to_numbers(self.plaintext))
     ciphertext = api.new('unsigned char[]', self.hexstr_to_numbers(self.ciphertext))
     output = api.new('unsigned char[]', len(plaintext))
     api.BIO_write(self.bio, ciphertext, len(ciphertext))
     api.BIO_write(self.bio, api.new('unsigned char[]', [0] * 1), 1)
     api.BIO_flush(self.bio)
     api.BIO_read(self.sink, output, len(output))
     self.assertEqual(bytes(api.buffer(plaintext)), bytes(api.buffer(output)))
Example #9
0
 def test_quick(self):
     buff = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE)
     key = api.new('char[]', self.key)
     data = api.new('char[]', self.data)
     size = api.new('unsigned int*')
     api.HMAC(self.md,
             api.cast('void*', key), len(self.key),
             api.cast('void*', data), len(self.data),
             api.cast('void*', buff), size)
     self.assertEqual(self.digest, api.buffer(buff, size[0])[:])
Example #10
0
 def test_0001_iteration(self):
     key = b'\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6'
     password = api.new('char[]', b'password')
     passlen = 8
     salt = api.new('char[]', b'salt')
     saltlen = 4
     iterations = 1
     keylen = 20
     out = api.new('unsigned char[]', keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, api.buffer(out)[:])
Example #11
0
def pbkdf2(password, length, salt=None, iterations=1000):
    "Derive a shared secret including encryption key from password"
    if salt is None:
        salt = random.getrandbytes(8)
    c_password = api.new('char[]', password)
    c_salt = api.new('char[]', salt)
    c_key = api.new('unsigned char[]', length)
    api.PKCS5_PBKDF2_HMAC_SHA1(c_password, len(password),
        c_salt, len(salt), iterations, length, c_key)
    secret = Secret(bytes(api.buffer(c_key)), salt, iterations)
    return secret
Example #12
0
 def test_single_decrypt(self):
     self.set_mode(enc=False)
     plaintext = api.new('unsigned char[]', self.hexstr_to_numbers(self.plaintext))
     ciphertext = api.new('unsigned char[]', self.hexstr_to_numbers(self.ciphertext))
     output = api.new('unsigned char[]', len(ciphertext)
             + api.EVP_CIPHER_CTX_block_size(self.ctx) - 1)
     outlen = api.new('int*')
     api.EVP_CipherUpdate(self.ctx, output, outlen, ciphertext, len(ciphertext))
     self.assertEqual(api.buffer(plaintext), api.buffer(output, outlen[0]))
     rval = api.EVP_CipherFinal_ex(self.ctx, output, outlen)
     self.assertEqual(rval, 1)
Example #13
0
def pbkdf2(password, length, salt=None, iterations=1000):
    "Derive a shared secret including encryption key from password"
    if salt is None:
        salt = random.getrandbytes(8)
    c_password = api.new('char[]', password)
    c_salt = api.new('char[]', salt)
    c_key = api.new('unsigned char[]', length)
    api.PKCS5_PBKDF2_HMAC_SHA1(c_password, len(password),
        c_salt, len(salt), iterations, length, c_key)
    secret = Secret(api.buffer(c_key)[:], salt, iterations)
    return secret
Example #14
0
 def test_0002_iteration(self):
     key = b'\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57'
     password = api.new('char[]', b'password')
     passlen = 8
     salt = api.new('char[]', b'salt')
     saltlen = 4
     iterations = 2
     keylen = 20
     out = api.new('unsigned char[]', keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, api.buffer(out)[:])
Example #15
0
 def test_4096_iteration(self):
     key = b'\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1'
     password = api.new('char[]', b'password')
     passlen = 8
     salt = api.new('char[]', b'salt')
     saltlen = 4
     iterations = 4096
     keylen = 20
     out = api.new('unsigned char[]', keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, api.buffer(out)[:])
Example #16
0
 def test_4096_3_iteration(self):
     key = b"\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34\x25\xe0\xc3"
     password = api.new("char[]", b"pass\0word")
     passlen = 9
     salt = api.new("char[]", b"sa\0lt")
     saltlen = 5
     iterations = 4096
     keylen = 16
     out = api.new("unsigned char[]", keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, bytes(api.buffer(out)))
Example #17
0
 def test_0002_iteration(self):
     key = b"\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"
     password = api.new("char[]", b"password")
     passlen = 8
     salt = api.new("char[]", b"salt")
     saltlen = 4
     iterations = 2
     keylen = 20
     out = api.new("unsigned char[]", keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, bytes(api.buffer(out)))
Example #18
0
 def test_4096_iteration(self):
     key = b"\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1"
     password = api.new("char[]", b"password")
     passlen = 8
     salt = api.new("char[]", b"salt")
     saltlen = 4
     iterations = 4096
     keylen = 20
     out = api.new("unsigned char[]", keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, bytes(api.buffer(out)))
Example #19
0
 def test_load_strings(self):
     lib = api.ERR_get_next_error_library()
     func = 1
     reason = 1
     code = api.ERR_PACK(lib, func, reason)
     array = api.new('ERR_STRING_DATA[2]')
     array[0].error = code
     array[0].string = api.new('char[]', b"MY ERROR")
     array[0].error = 0
     array[0].string = api.NULL
     api.ERR_load_strings(lib, array)
Example #20
0
 def test_0001_iteration(self):
     key = b"\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"
     password = api.new("char[]", b"password")
     passlen = 8
     salt = api.new("char[]", b"salt")
     saltlen = 4
     iterations = 1
     keylen = 20
     out = api.new("unsigned char[]", keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, bytes(api.buffer(out)))
Example #21
0
 def test_4096_2_iteration(self):
     key = b'\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38'
     password = api.new('char[]', b'passwordPASSWORDpassword')
     passlen = 24
     salt = api.new('char[]', b'saltSALTsaltSALTsaltSALTsaltSALTsalt')
     saltlen = 36
     iterations = 4096
     keylen = 25
     out = api.new('unsigned char[]', keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, api.buffer(out)[:])
Example #22
0
 def test_4096_3_iteration(self):
     key = b'\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34\x25\xe0\xc3'
     password = api.new('char[]', b'pass\0word')
     passlen = 9
     salt = api.new('char[]', b'sa\0lt')
     saltlen = 5
     iterations = 4096
     keylen = 16
     out = api.new('unsigned char[]', keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, api.buffer(out)[:])
Example #23
0
 def test_4096_2_iteration(self):
     key = b"\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38"
     password = api.new("char[]", b"passwordPASSWORDpassword")
     passlen = 24
     salt = api.new("char[]", b"saltSALTsaltSALTsaltSALTsaltSALTsalt")
     saltlen = 36
     iterations = 4096
     keylen = 25
     out = api.new("unsigned char[]", keylen)
     api.PKCS5_PBKDF2_HMAC_SHA1(password, passlen, salt, saltlen, iterations, keylen, out)
     self.assertEqual(key, bytes(api.buffer(out)))
Example #24
0
 def test_bio_read_write(self):
     try:
         method = api.BIO_s_mem()
         mem = api.BIO_new(method)
         data = api.new('char[]', b"HELLO WORLD")
         api.BIO_write(mem, data, 11)
         buf = api.new('char[]', 5)
         api.BIO_read(mem, buf, len(buf))
         self.assertEqual(api.string(buf), b"HELLO")
         api.BIO_gets(mem, buf, len(buf))
         self.assertEqual(api.string(buf), b" WOR")
     finally:
         api.BIO_free(mem)
Example #25
0
 def test_long(self):
     buff = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE)
     key = api.new('char[]', self.key)
     data = api.new('char[]', self.data)
     size = api.new('unsigned int*')
     ctx = api.new('HMAC_CTX*')
     api.HMAC_CTX_init(ctx)
     api.HMAC_Init_ex(ctx, api.cast('void*', key), len(self.key),
             self.md, api.NULL)
     api.HMAC_Update(ctx, api.cast('void*', data), len(self.data))
     api.HMAC_Final(ctx, buff, size)
     api.HMAC_CTX_cleanup(ctx)
     self.assertEqual(self.digest, api.buffer(buff, size[0])[:])
Example #26
0
 def test_multiple_updates(self):
     buff = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE)
     key = api.new('char[]', self.key)
     data = api.new('char[]', self.data)
     size = api.new('unsigned int*')
     ctx = api.new('HMAC_CTX*')
     api.HMAC_CTX_init(ctx)
     api.HMAC_Init_ex(ctx, api.cast('void*', key), len(self.key),
             self.md, api.NULL)
     for pos in range(len(self.data)):
         api.HMAC_Update(ctx, api.cast('void*', data+pos), 1)
     api.HMAC_Final(ctx, buff, size)
     api.HMAC_CTX_cleanup(ctx)
     self.assertEqual(self.digest, bytes(api.buffer(buff, size[0])))
Example #27
0
 def _digest(self):
     "Return iterator for digest byte data."
     buff = api.new('unsigned char[]', api.EVP_MAX_MD_SIZE)
     size = api.new('unsigned int*')
     context = api.new('EVP_MD_CTX*')
     if not api.EVP_DigestInit_ex(context, self._md, api.NULL):
         raise DigestError('Failed to initialise message digest')
     if not api.EVP_MD_CTX_copy_ex(context, self._context):
         raise DigestError('Failed to copy message digest')
     if not api.EVP_DigestFinal_ex(context, buff, size):
         raise DigestError('Failed to retrieve digest value')
     if not api.EVP_MD_CTX_cleanup(context):
         raise DigestError('Failed to cleanup message digest')
     return buff, size[0]
Example #28
0
 def test_multiple_encrypt(self):
     self.set_mode(enc=True)
     numbers = self.hexstr_to_numbers(self.plaintext)
     ciphertext = api.new('unsigned char[]', self.hexstr_to_numbers(self.ciphertext))
     outbuf = api.new('unsigned char[]', api.EVP_CIPHER_CTX_block_size(self.ctx))
     outlen = api.new('int*')
     output = b''
     for num in numbers:
         plaintext = api.new('unsigned char[]', [num])
         api.EVP_CipherUpdate(self.ctx, outbuf, outlen, plaintext, len(plaintext))
         if outlen[0] > 0:
             output += bytes(api.buffer(outbuf, outlen[0]))
     self.assertEqual(bytes(api.buffer(ciphertext)), output)
     rval = api.EVP_CipherFinal_ex(self.ctx, outbuf, outlen)
     self.assertEqual(rval, 1)
Example #29
0
 def __init__(self, filename, mode='r'):
     if mode not in self.MODES:
         msg = "mode string must begin with one of "
         msg += " ".join("'{0}'".format(m) for m in sorted(self.MODES))
         msg += " not '{0}'".format(mode)
         raise ValueError(msg)
     self._filename = filename.encode()
     self._mode = mode.encode()
     mode = api.new('char[]', self._mode)
     filename = api.new('char[]', self._filename)
     bio = api.BIO_new_file(filename, mode)
     if api.cast('void*', bio) == api.NULL:
         messages = err.log_errors()
         raise IOError(messages[0])
     super(BIOFile, self).__init__(bio)
Example #30
0
 def update(self, msg):
     """Update this hashing object with the string msg.
     """
     if self._ctx is None:
         raise ValueError('HMAC already closed')
     data = api.new('char[]', msg)
     api.HMAC_Update(self._ctx, api.cast('void*', data), len(msg))
Example #31
0
 def __init__(self, encrypt=True, algorithm=b'AES-128-CBC', digest=b'SHA1'):
     self._algorithm = algorithm
     self._digest = digest
     # initialise attributes to empty
     self._encrypting = bool(encrypt)
     self._initialised = False
     self._bio = api.NULL
     self._cipher = api.NULL
     self._ctx = api.NULL
     self._sink = api.NULL
     self._hmac = None
     self._weakrefs = []
     # create cipher object from cipher name
     cipher = api.EVP_get_cipherbyname(algorithm)
     if cipher == api.NULL:
         msg = "Unknown cipher name '{0}'".format(algorithm)
         raise ValueError(msg)
     self._cipher = cipher
     # allocate cipher context pointer
     self._ctxptr = api.new('EVP_CIPHER_CTX*[]', 1)
     # create bio chain (cipher, buffer, mem)
     self._sink = api.BIO_new(api.BIO_s_mem())
     bio = api.BIO_push(api.BIO_new(api.BIO_f_buffer()), self._sink)
     bio = api.BIO_push(api.BIO_new(api.BIO_f_cipher()), bio)
     cleanup = lambda _: api.BIO_free_all(bio)
     self._weakrefs.append(weakref.ref(self, cleanup))
     self._bio = bio
     # initialise cipher context
     api.BIO_get_cipher_ctx(bio, self._ctxptr)
     self._ctx = self._ctxptr[0]
     if not api.EVP_CipherInit_ex(self._ctx,
             cipher, api.NULL, api.NULL, api.NULL, 1 if encrypt else 0):
         raise ValueError("Unable to initialise cipher")
Example #32
0
 def setUp(self):
     self.buff = api.new('char[]', self.DATA)
     self.filter = api.BIO_new(api.BIO_f_null())
     self.sink = api.BIO_new_mem_buf(self.buff, len(self.DATA))
     self.bio = api.BIO_push(self.filter, self.sink)
     self.fileobj = io.BIOChain(self.bio)
Example #33
0
 def getrandbytes(self, length):
     "getrandbytes(k) -> 's'. Generate a byte string with k random bytes."
     buff = api.new('unsigned char[]', length)
     self._rand_bytes(buff, length)
     return api.buffer(buff)[:]