HKDF vector creation¶
This page documents the code that was used to generate a longer HKDF test vector (1200 bytes) than is available in RFC 5869. All the vectors were generated using OpenSSL and verified with Go.
Creation¶
The following Python script was run to generate the vector files.
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import binascii
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
IKM = binascii.unhexlify(b"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
L = 1200
OKM = HKDF(
algorithm=hashes.SHA256(),
length=L,
salt=None,
info=None,
).derive(IKM)
def _build_vectors():
output = [
"COUNT = 0",
"Hash = SHA-256",
"IKM = " + binascii.hexlify(IKM).decode("ascii"),
"salt = ",
"info = ",
"L = {}".format(L),
"OKM = " + binascii.hexlify(OKM).decode("ascii"),
]
return "\n".join(output)
def _write_file(data, filename):
with open(filename, "w") as f:
f.write(data)
if __name__ == "__main__":
_write_file(_build_vectors(), "hkdf.txt")
Download link: generate_hkdf.py
Verification¶
The following Go code was used to verify the vectors.
package main
import (
"bufio"
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"golang.org/x/crypto/hkdf"
"io"
"os"
"strconv"
"strings"
)
func unhexlify(s string) []byte {
bytes, err := hex.DecodeString(s)
if err != nil {
panic(err)
}
return bytes
}
func verifier(l uint64, ikm, okm []byte) bool {
hash := sha256.New
hkdf := hkdf.New(hash, ikm, nil, nil)
okmComputed := make([]byte, l)
io.ReadFull(hkdf, okmComputed)
return bytes.Equal(okmComputed, okm)
}
func validateVectors(filename string) bool {
vectors, err := os.Open(filename)
if err != nil {
panic(err)
}
defer vectors.Close()
var segments []string
var l uint64
var ikm, okm string
scanner := bufio.NewScanner(vectors)
for scanner.Scan() {
segments = strings.Split(scanner.Text(), " = ")
switch {
case strings.ToUpper(segments[0]) == "L":
l, err = strconv.ParseUint(segments[1], 10, 64)
if err != nil {
panic(err)
}
case strings.ToUpper(segments[0]) == "IKM":
ikm = segments[1]
case strings.ToUpper(segments[0]) == "OKM":
okm = segments[1]
}
}
return verifier(l, unhexlify(ikm), unhexlify(okm))
}
func main() {
if validateVectors("vectors/cryptography_vectors/KDF/hkdf-generated.txt") {
fmt.Println("HKDF OK.")
} else {
fmt.Println("HKDF failed.")
os.Exit(1)
}
}
Download link: verify_hkdf.go