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). 16 import Base 17 import bend-osdev-bytes@0.1.0.0/bytes.bend as B 18 import ./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) 22 def 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))