Пример #1
0
    def derive(self, key_material):
        utils._check_byteslike("key_material", key_material)
        if self._used:
            raise AlreadyFinalized

        self._used = True
        return self._expand(key_material)
Пример #2
0
 def _check_params(self, nonce: bytes, data: bytes,
                   associated_data: bytes) -> None:
     utils._check_byteslike("nonce", nonce)
     utils._check_bytes("data", data)
     utils._check_bytes("associated_data", associated_data)
     if len(nonce) != 12:
         raise ValueError("Nonce must be 12 bytes")
Пример #3
0
 def _check_params(self, nonce: bytes, data: bytes,
                   associated_data: bytes) -> None:
     utils._check_byteslike("nonce", nonce)
     utils._check_bytes("data", data)
     utils._check_bytes("associated_data", associated_data)
     if not 7 <= len(nonce) <= 13:
         raise ValueError("Nonce must be between 7 and 13 bytes")
Пример #4
0
    def __init__(self, tweak):
        utils._check_byteslike("tweak", tweak)

        if len(tweak) != 16:
            raise ValueError("tweak must be 128-bits (16 bytes)")

        self._tweak = tweak
Пример #5
0
    def derive(self, key_material: bytes) -> bytes:
        if self._used:
            raise AlreadyFinalized

        utils._check_byteslike("key_material", key_material)
        self._used = True

        # inverse floor division (equivalent to ceiling)
        rounds = -(-self._length // self._algorithm.digest_size)

        output = [b""]

        # For counter mode, the number of iterations shall not be
        # larger than 2^r-1, where r <= 32 is the binary length of the counter
        # This ensures that the counter values used as an input to the
        # PRF will not repeat during a particular call to the KDF function.
        r_bin = utils.int_to_bytes(1, self._rlen)
        if rounds > pow(2, len(r_bin) * 8) - 1:
            raise ValueError("There are too many iterations.")

        for i in range(1, rounds + 1):
            h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)

            counter = utils.int_to_bytes(i, self._rlen)
            if self._location == CounterLocation.BeforeFixed:
                h.update(counter)

            h.update(self._generate_fixed_input())

            if self._location == CounterLocation.AfterFixed:
                h.update(counter)

            output.append(h.finalize())

        return b"".join(output)[:self._length]
Пример #6
0
    def derive(self, key_material: bytes) -> bytes:
        utils._check_byteslike("key_material", key_material)
        if self._used:
            raise AlreadyFinalized

        self._used = True
        return self._expand(key_material)
    def __init__(self, tweak):
        utils._check_byteslike("tweak", tweak)

        if len(tweak) != 16:
            raise ValueError("tweak must be 128-bits (16 bytes)")

        self._tweak = tweak
Пример #8
0
 def _check_params(self, nonce: bytes, data: bytes,
                   associated_data: bytes) -> None:
     utils._check_byteslike("nonce", nonce)
     utils._check_bytes("data", data)
     utils._check_bytes("associated_data", associated_data)
     if len(nonce) < 8 or len(nonce) > 128:
         raise ValueError("Nonce must be between 8 and 128 bytes")
Пример #9
0
    def derive(self, key_material):
        if self._used:
            raise AlreadyFinalized

        utils._check_byteslike("key_material", key_material)
        self._used = True

        # inverse floor division (equivalent to ceiling)
        rounds = -(-self._length // self._algorithm.digest_size)

        output = [b'']

        # For counter mode, the number of iterations shall not be
        # larger than 2^r-1, where r <= 32 is the binary length of the counter
        # This ensures that the counter values used as an input to the
        # PRF will not repeat during a particular call to the KDF function.
        r_bin = utils.int_to_bytes(1, self._rlen)
        if rounds > pow(2, len(r_bin) * 8) - 1:
            raise ValueError('There are too many iterations.')

        for i in range(1, rounds + 1):
            h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)

            counter = utils.int_to_bytes(i, self._rlen)
            if self._location == CounterLocation.BeforeFixed:
                h.update(counter)

            h.update(self._generate_fixed_input())

            if self._location == CounterLocation.AfterFixed:
                h.update(counter)

            output.append(h.finalize())

        return b''.join(output)[:self._length]
Пример #10
0
    def __init__(self, key, nonce):
        self.key = _verify_key_size(self, key)
        utils._check_byteslike("nonce", nonce)

        if len(nonce) != 16:
            raise ValueError("nonce must be 128-bits (16 bytes)")

        self._nonce = nonce
Пример #11
0
    def derive(self, key_material):
        if self._used:
            raise AlreadyFinalized("Scrypt instances can only be used once.")
        self._used = True

        utils._check_byteslike("key_material", key_material)
        return self._backend.derive_scrypt(key_material, self._salt,
                                           self._length, self._n, self._r,
                                           self._p)
def _verify_key_size(algorithm, key):
    # Verify that the key is instance of bytes
    utils._check_byteslike("key", key)

    # Verify that the key size matches the expected key size
    if len(key) * 8 not in algorithm.key_sizes:
        raise ValueError("Invalid key size ({}) for {}.".format(
            len(key) * 8, algorithm.name))
    return key
Пример #13
0
    def derive(self, key_material):
        if self._used:
            raise AlreadyFinalized("Scrypt instances can only be used once.")
        self._used = True

        utils._check_byteslike("key_material", key_material)
        return self._backend.derive_scrypt(
            key_material, self._salt, self._length, self._n, self._r, self._p
        )
Пример #14
0
    def derive(self, key_material):
        if self._used:
            raise AlreadyFinalized("PBKDF2 instances can only be used once.")
        self._used = True

        utils._check_byteslike("key_material", key_material)
        return self._backend.derive_pbkdf2_hmac(self._algorithm, self._length,
                                                self._salt, self._iterations,
                                                key_material)
Пример #15
0
def _verify_key_size(algorithm, key):
    # Verify that the key is instance of bytes
    utils._check_byteslike("key", key)

    # Verify that the key size matches the expected key size
    if len(key) * 8 not in algorithm.key_sizes:
        raise ValueError("Invalid key size ({0}) for {1}.".format(
            len(key) * 8, algorithm.name
        ))
    return key
Пример #16
0
    def derive(self, key_material: bytes) -> bytes:
        if self._used:
            raise AlreadyFinalized("Scrypt instances can only be used once.")
        self._used = True

        utils._check_byteslike("key_material", key_material)
        from cryptography.hazmat.backends.openssl.backend import backend

        return backend.derive_scrypt(key_material, self._salt, self._length,
                                     self._n, self._r, self._p)
Пример #17
0
    def __init__(self, key):
        if not backend.aead_cipher_supported(self):
            raise exceptions.UnsupportedAlgorithm(
                "ChaCha20Poly1305 is not supported by this version of OpenSSL",
                exceptions._Reasons.UNSUPPORTED_CIPHER)
        utils._check_byteslike("key", key)

        if len(key) != 32:
            raise ValueError("ChaCha20Poly1305 key must be 32 bytes.")

        self._key = key
Пример #18
0
    def __init__(self, key: bytes):
        utils._check_byteslike("key", key)
        if len(key) not in (32, 48, 64):
            raise ValueError("AESSIV key must be 256, 384, or 512 bits.")

        self._key = key

        if not backend.aead_cipher_supported(self):
            raise exceptions.UnsupportedAlgorithm(
                "AES-SIV is not supported by this version of OpenSSL",
                exceptions._Reasons.UNSUPPORTED_CIPHER,
            )
Пример #19
0
    def __init__(self, key):
        if not backend.aead_cipher_supported(self):
            raise exceptions.UnsupportedAlgorithm(
                "ChaCha20Poly1305 is not supported by this version of OpenSSL",
                exceptions._Reasons.UNSUPPORTED_CIPHER
            )
        utils._check_byteslike("key", key)

        if len(key) != 32:
            raise ValueError("ChaCha20Poly1305 key must be 32 bytes.")

        self._key = key
Пример #20
0
    def __init__(self, key: bytes):
        utils._check_byteslike("key", key)
        if len(key) not in (16, 24, 32):
            raise ValueError("AESOCB3 key must be 128, 192, or 256 bits.")

        self._key = key

        if not backend.aead_cipher_supported(self):
            raise exceptions.UnsupportedAlgorithm(
                "OCB3 is not supported by this version of OpenSSL",
                exceptions._Reasons.UNSUPPORTED_CIPHER,
            )
Пример #21
0
    def derive(self, key_material):
        if self._used:
            raise AlreadyFinalized("PBKDF2 instances can only be used once.")
        self._used = True

        utils._check_byteslike("key_material", key_material)
        return self._backend.derive_pbkdf2_hmac(
            self._algorithm,
            self._length,
            self._salt,
            self._iterations,
            key_material
        )
Пример #22
0
    def __init__(self, key, tag_length=16):
        utils._check_byteslike("key", key)
        if len(key) not in (16, 24, 32):
            raise ValueError("AESCCM key must be 128, 192, or 256 bits.")

        self._key = key
        if not isinstance(tag_length, int):
            raise TypeError("tag_length must be an integer")

        if tag_length not in (4, 6, 8, 10, 12, 14, 16):
            raise ValueError("Invalid tag_length")

        self._tag_length = tag_length
Пример #23
0
def _byte_unpadding_update(buffer_, data, block_size):
    if buffer_ is None:
        raise AlreadyFinalized("Context was already finalized.")

    utils._check_byteslike("data", data)

    buffer_ += bytes(data)

    finished_blocks = max(len(buffer_) // (block_size // 8) - 1, 0)

    result = buffer_[:finished_blocks * (block_size // 8)]
    buffer_ = buffer_[finished_blocks * (block_size // 8):]

    return buffer_, result
Пример #24
0
def _byte_padding_update(buffer_: typing.Optional[bytes], data: bytes,
                         block_size: int):
    if buffer_ is None:
        raise AlreadyFinalized("Context was already finalized.")

    utils._check_byteslike("data", data)

    buffer_ += bytes(data)

    finished_blocks = len(buffer_) // (block_size // 8)

    result = buffer_[:finished_blocks * (block_size // 8)]
    buffer_ = buffer_[finished_blocks * (block_size // 8):]

    return buffer_, result
Пример #25
0
    def derive(self, key_material: bytes) -> bytes:
        if self._used:
            raise AlreadyFinalized("PBKDF2 instances can only be used once.")
        self._used = True

        utils._check_byteslike("key_material", key_material)
        from cryptography.hazmat.backends.openssl.backend import backend

        return backend.derive_pbkdf2_hmac(
            self._algorithm,
            self._length,
            self._salt,
            self._iterations,
            key_material,
        )
Пример #26
0
def _concatkdf_derive(key_material, length, auxfn, otherinfo):
    utils._check_byteslike("key_material", key_material)
    output = [b""]
    outlen = 0
    counter = 1

    while (length > outlen):
        h = auxfn()
        h.update_user(_int_to_u32be(counter))
        h.update_user(key_material)
        h.update_user(otherinfo)
        output.append(h.finalize())
        outlen += len(output[-1])
        counter += 1

    return b"".join(output)[:length]
Пример #27
0
def _concatkdf_derive(key_material, length, auxfn, otherinfo):
    utils._check_byteslike("key_material", key_material)
    output = [b""]
    outlen = 0
    counter = 1

    while (length > outlen):
        h = auxfn()
        h.update(_int_to_u32be(counter))
        h.update(key_material)
        h.update(otherinfo)
        output.append(h.finalize())
        outlen += len(output[-1])
        counter += 1

    return b"".join(output)[:length]
Пример #28
0
def _byte_unpadding_update(buffer_, data, block_size):
    if buffer_ is None:
        raise AlreadyFinalized("Context was already finalized.")

    utils._check_byteslike("data", data)

    # six.PY2: Only coerce non-bytes objects to avoid triggering bad behavior
    # of future's newbytes type. Unconditionally call bytes() after Python 2
    # support is gone.
    buffer_ += data if isinstance(data, bytes) else bytes(data)

    finished_blocks = max(len(buffer_) // (block_size // 8) - 1, 0)

    result = buffer_[:finished_blocks * (block_size // 8)]
    buffer_ = buffer_[finished_blocks * (block_size // 8):]

    return buffer_, result
Пример #29
0
    def __init__(self, key, tag_length=16):
        utils._check_byteslike("key", key)
        if len(key) not in (16, 24, 32):
            raise ValueError("AESCCM key must be 128, 192, or 256 bits.")

        self._key = key
        if not isinstance(tag_length, int):
            raise TypeError("tag_length must be an integer")

        if tag_length not in (4, 6, 8, 10, 12, 14, 16):
            raise ValueError("Invalid tag_length")

        self._tag_length = tag_length

        if not backend.aead_cipher_supported(self):
            raise exceptions.UnsupportedAlgorithm(
                "AESCCM is not supported by this version of OpenSSL",
                exceptions._Reasons.UNSUPPORTED_CIPHER)
Пример #30
0
 def __init__(self, initialization_vector, tag=None, min_tag_length=16):
     # len(initialization_vector) must in [1, 2 ** 64), but it's impossible
     # to actually construct a bytes object that large, so we don't check
     # for it
     utils._check_byteslike("initialization_vector", initialization_vector)
     if len(initialization_vector) == 0:
         raise ValueError("initialization_vector must be at least 1 byte")
     self._initialization_vector = initialization_vector
     if tag is not None:
         utils._check_bytes("tag", tag)
         if min_tag_length < 4:
             raise ValueError("min_tag_length must be >= 4")
         if len(tag) < min_tag_length:
             raise ValueError(
                 "Authentication tag must be {} bytes or longer.".format(
                     min_tag_length))
     self._tag = tag
     self._min_tag_length = min_tag_length
Пример #31
0
 def __init__(self, initialization_vector, tag=None, min_tag_length=16):
     # len(initialization_vector) must in [1, 2 ** 64), but it's impossible
     # to actually construct a bytes object that large, so we don't check
     # for it
     utils._check_byteslike("initialization_vector", initialization_vector)
     if len(initialization_vector) == 0:
         raise ValueError("initialization_vector must be at least 1 byte")
     self._initialization_vector = initialization_vector
     if tag is not None:
         utils._check_bytes("tag", tag)
         if min_tag_length < 4:
             raise ValueError("min_tag_length must be >= 4")
         if len(tag) < min_tag_length:
             raise ValueError(
                 "Authentication tag must be {} bytes or longer.".format(
                     min_tag_length)
             )
     self._tag = tag
     self._min_tag_length = min_tag_length
Пример #32
0
    def __init__(self, key, tag_length=16):
        utils._check_byteslike("key", key)
        if len(key) not in (16, 24, 32):
            raise ValueError("AESCCM key must be 128, 192, or 256 bits.")

        self._key = key
        if not isinstance(tag_length, int):
            raise TypeError("tag_length must be an integer")

        if tag_length not in (4, 6, 8, 10, 12, 14, 16):
            raise ValueError("Invalid tag_length")

        self._tag_length = tag_length

        if not backend.aead_cipher_supported(self):
            raise exceptions.UnsupportedAlgorithm(
                "AESCCM is not supported by this version of OpenSSL",
                exceptions._Reasons.UNSUPPORTED_CIPHER
            )
Пример #33
0
 def __init__(self, initialization_vector, tag=None, min_tag_length=16):
     # OpenSSL 3.0.0 constrains GCM IVs to [64, 1024] bits inclusive
     # This is a sane limit anyway so we'll enforce it here.
     utils._check_byteslike("initialization_vector", initialization_vector)
     if len(initialization_vector) < 8 or len(initialization_vector) > 128:
         raise ValueError(
             "initialization_vector must be between 8 and 128 bytes (64 "
             "and 1024 bits).")
     self._initialization_vector = initialization_vector
     if tag is not None:
         utils._check_bytes("tag", tag)
         if min_tag_length < 4:
             raise ValueError("min_tag_length must be >= 4")
         if len(tag) < min_tag_length:
             raise ValueError(
                 "Authentication tag must be {} bytes or longer.".format(
                     min_tag_length))
     self._tag = tag
     self._min_tag_length = min_tag_length
Пример #34
0
def load_ssh_public_key(
        data: bytes,
        backend: typing.Optional[Backend] = None) -> _SSH_PUBLIC_KEY_TYPES:
    """Load public key from OpenSSH one-line format."""
    backend = _get_backend(backend)
    utils._check_byteslike("data", data)

    m = _SSH_PUBKEY_RC.match(data)
    if not m:
        raise ValueError("Invalid line format")
    key_type = orig_key_type = m.group(1)
    key_body = m.group(2)
    with_cert = False
    if _CERT_SUFFIX == key_type[-len(_CERT_SUFFIX):]:
        with_cert = True
        key_type = key_type[:-len(_CERT_SUFFIX)]
    kformat = _lookup_kformat(key_type)

    try:
        data = memoryview(binascii.a2b_base64(key_body))
    except (TypeError, binascii.Error):
        raise ValueError("Invalid key format")

    inner_key_type, data = _get_sshstr(data)
    if inner_key_type != orig_key_type:
        raise ValueError("Invalid key format")
    if with_cert:
        nonce, data = _get_sshstr(data)
    public_key, data = kformat.load_public(key_type, data, backend)
    if with_cert:
        serial, data = _get_u64(data)
        cctype, data = _get_u32(data)
        key_id, data = _get_sshstr(data)
        principals, data = _get_sshstr(data)
        valid_after, data = _get_u64(data)
        valid_before, data = _get_u64(data)
        crit_options, data = _get_sshstr(data)
        extensions, data = _get_sshstr(data)
        reserved, data = _get_sshstr(data)
        sig_key, data = _get_sshstr(data)
        signature, data = _get_sshstr(data)
    _check_empty(data)
    return public_key
Пример #35
0
    def derive(self, key_material):
        if self._used:
            raise AlreadyFinalized
        self._used = True
        utils._check_byteslike("key_material", key_material)
        output = [b""]
        outlen = 0
        counter = 1

        while self._length > outlen:
            h = hashes.Hash(self._algorithm, self._backend)
            h.update(key_material)
            h.update(_int_to_u32be(counter))
            if self._sharedinfo is not None:
                h.update(self._sharedinfo)
            output.append(h.finalize())
            outlen += len(output[-1])
            counter += 1

        return b"".join(output)[:self._length]
Пример #36
0
    def derive(self, key_material: bytes) -> bytes:
        if self._used:
            raise AlreadyFinalized
        self._used = True
        utils._check_byteslike("key_material", key_material)
        output = [b""]
        outlen = 0
        counter = 1

        while self._length > outlen:
            h = hashes.Hash(self._algorithm)
            h.update(key_material)
            h.update(_int_to_u32be(counter))
            if self._sharedinfo is not None:
                h.update(self._sharedinfo)
            output.append(h.finalize())
            outlen += len(output[-1])
            counter += 1

        return b"".join(output)[:self._length]
def _concatkdf_derive(
    key_material: bytes,
    length: int,
    auxfn: typing.Callable[[], hashes.HashContext],
    otherinfo: bytes,
) -> bytes:
    utils._check_byteslike("key_material", key_material)
    output = [b""]
    outlen = 0
    counter = 1

    while length > outlen:
        h = auxfn()
        h.update(_int_to_u32be(counter))
        h.update(key_material)
        h.update(otherinfo)
        output.append(h.finalize())
        outlen += len(output[-1])
        counter += 1

    return b"".join(output)[:length]
Пример #38
0
 def update(self, data: bytes) -> None:
     if self._ctx is None:
         raise AlreadyFinalized("Context was already finalized.")
     utils._check_byteslike("data", data)
     self._ctx.update(data)
Пример #39
0
def load_ssh_private_key(data, password, backend):
    """Load private key from OpenSSH custom encoding.
    """
    utils._check_byteslike("data", data)
    if password is not None:
        utils._check_bytes("password", password)

    m = _PEM_RC.search(data)
    if not m:
        raise ValueError("Not OpenSSH private key format")
    p1 = m.start(1)
    p2 = m.end(1)
    data = binascii.a2b_base64(memoryview(data)[p1:p2])
    if not data.startswith(_SK_MAGIC):
        raise ValueError("Not OpenSSH private key format")
    data = memoryview(data)[len(_SK_MAGIC):]

    # parse header
    ciphername, data = _get_sshstr(data)
    kdfname, data = _get_sshstr(data)
    kdfoptions, data = _get_sshstr(data)
    nkeys, data = _get_u32(data)
    if nkeys != 1:
        raise ValueError("Only one key supported")

    # load public key data
    pubdata, data = _get_sshstr(data)
    pub_key_type, pubdata = _get_sshstr(pubdata)
    kformat = _lookup_kformat(pub_key_type)
    pubfields, pubdata = kformat.get_public(pubdata)
    _check_empty(pubdata)

    # load secret data
    edata, data = _get_sshstr(data)
    _check_empty(data)

    if (ciphername, kdfname) != (_NONE, _NONE):
        ciphername = ciphername.tobytes()
        if ciphername not in _SSH_CIPHERS:
            raise UnsupportedAlgorithm("Unsupported cipher: %r" % ciphername)
        if kdfname != _BCRYPT:
            raise UnsupportedAlgorithm("Unsupported KDF: %r" % kdfname)
        blklen = _SSH_CIPHERS[ciphername][3]
        _check_block_size(edata, blklen)
        salt, kbuf = _get_sshstr(kdfoptions)
        rounds, kbuf = _get_u32(kbuf)
        _check_empty(kbuf)
        ciph = _init_cipher(ciphername, password, salt.tobytes(), rounds,
                            backend)
        edata = memoryview(ciph.decryptor().update(edata))
    else:
        blklen = 8
        _check_block_size(edata, blklen)
    ck1, edata = _get_u32(edata)
    ck2, edata = _get_u32(edata)
    if ck1 != ck2:
        raise ValueError("Corrupt data: broken checksum")

    # load per-key struct
    key_type, edata = _get_sshstr(edata)
    if key_type != pub_key_type:
        raise ValueError("Corrupt data: key type mismatch")
    private_key, edata = kformat.load_private(edata, pubfields, backend)
    comment, edata = _get_sshstr(edata)

    # yes, SSH does padding check *after* all other parsing is done.
    # need to follow as it writes zero-byte padding too.
    if edata != _PADDING[:len(edata)]:
        raise ValueError("Corrupt data: invalid padding")

    return private_key
Пример #40
0
 def _check_params(self, nonce, data, associated_data):
     utils._check_byteslike("nonce", nonce)
     utils._check_bytes("data", data)
     utils._check_bytes("associated_data", associated_data)
     if not 7 <= len(nonce) <= 13:
         raise ValueError("Nonce must be between 7 and 13 bytes")
Пример #41
0
    def set_data(self, data: bytes) -> "PKCS7SignatureBuilder":
        _check_byteslike("data", data)
        if self._data is not None:
            raise ValueError("data may only be set once")

        return PKCS7SignatureBuilder(data, self._signers)
Пример #42
0
 def _check_params(self, nonce, data, associated_data):
     utils._check_byteslike("nonce", nonce)
     utils._check_bytes("data", data)
     utils._check_bytes("associated_data", associated_data)
     if len(nonce) != 12:
         raise ValueError("Nonce must be 12 bytes")
 def __init__(self, initialization_vector):
     utils._check_byteslike("initialization_vector", initialization_vector)
     self._initialization_vector = initialization_vector
Пример #44
0
 def update(self, data):
     if self._ctx is None:
         raise AlreadyFinalized("Context was already finalized.")
     utils._check_byteslike("data", data)
     self._ctx.update(data)
Пример #45
0
 def derive(self, key_material):
     utils._check_byteslike("key_material", key_material)
     return self._hkdf_expand.derive(self._extract(key_material))
Пример #46
0
    def __init__(self, key):
        utils._check_byteslike("key", key)
        if len(key) not in (16, 24, 32):
            raise ValueError("AESGCM key must be 128, 192, or 256 bits.")

        self._key = key
Пример #47
0
 def __init__(self, initialization_vector):
     utils._check_byteslike("initialization_vector", initialization_vector)
     self._initialization_vector = initialization_vector
Пример #48
0
 def __init__(self, nonce):
     utils._check_byteslike("nonce", nonce)
     self._nonce = nonce