kdf.bend
1# The KDF interface (key derivation).
2#
3# A KDF (one template argument):
4# ~derive: B.Octets -> B.Octets -> B.Octets -> Nat -> Result<&2, &2, CrError, B.Octets>
5# secret, salt, context (info), length: that many bytes of keying
6# material, or the refusal of a length the KDF cannot give
7# (CrBadOutputLength)
8# Laws (README.md, "Laws"):
9# length a derivation that succeeds gives exactly the length asked for
10# (tested)
11# prefix a shorter derivation is a prefix of a longer one with the same
12# inputs (tested)
13#
14# The instances: HKDF over any hash (hkdf.bend), PBKDF2 over any MAC
15# (pbkdf2.bend).
16import Base
17import bend-osdev-bytes@0.1.0.0/bytes.bend as B
18import bend-osdev-crypto@0.1.0.0/crypto.bend as Cr
19
20# A key for any interface derived from a secret: n bytes, through that
21# interface's key schedule ~key (a block cipher's, a MAC's, an AEAD's)
22def CrKdf.derive_key(~K: Data, ~derive: B.Octets -> B.Octets -> B.Octets -> Nat -> Result<&2, &2, Cr.CrError, B.Octets>, ~key: B.Octets -> Result<&2, &2, Cr.CrError, K>, secret: B.Octets, salt: B.Octets, info: B.Octets, n: Nat) -> Result<&2, &2, Cr.CrError, K>:
23 Result.bind(&2, &2, Cr.CrError, B.Octets, K, derive(secret, salt, info, n), o => key(o))