Skip to content

HKDF key-length inconsistency #3211

@burgerdev

Description

@burgerdev

For too small key sizes, HKDF.derive() outputs an empty array instead of a small key:

Program:

#!/usr/bin/env python3.5
import cryptography
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.backends import default_backend

print("cryptography.io:{}".format(cryptography.__version__))

hkdf = HKDF(algorithm=hashes.SHA256(), length=4, salt=b"salt",
            info=b"some-test", backend=default_backend())

key = hkdf.derive(b"my secret passphrase")
print("Derived key: {}".format(key))

Output:

cryptography.io:1.5.2
Derived key: b''

Suggested fix:

I am not quite sure why the division by 8 in the snippet below was added. The cumulative size of the output array is always self._algorithm.digest_size * len(output) and thus we can stop after self._algorithm.digest_size * len(output) >= self._length. At first I thought this might be a clever trick taken from the paper, but I didn't find it there. I guess there was a mixup between bits and bytes at some point.

# class HKDFExpand
def _expand(self, key_material):
        output = [b""]
        counter = 1

        while (self._algorithm.digest_size // 8) * len(output) < self._length:
            h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)
            h.update(output[-1])
            h.update(self._info)
            h.update(six.int2byte(counter))
            output.append(h.finalize())
            counter += 1

        return b"".join(output)[:self._length]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions