// Author: cirakg & claude ai // Summary: HKDF-SHA256 (RFC 5869) on the native HMAC, small enough for the glance. // // The key derivation SealedBox and KeyManager use for every sub-key. It // lives apart from Kdf (PBKDF2, which needs the job system) so the glance // can open the sealed favourite code (GlanceCode) with only the crypto it // needs. Verified with RFC 5869 test cases 1 to 3 (test/crypto/KdfAesTest.mc) // and in the start-up self-test. import Toybox.Lang; (:glance) module Hkdf { const HASH_BYTES = 32; // Extract with salt (empty means 32 zero bytes), then expand to // `length` bytes with info. length <= 255 * 32. function derive(ikm as ByteArray, salt as ByteArray, info as ByteArray, length as Number) as ByteArray { if (length < 1 || length > 255 * HASH_BYTES) { throw new Lang.InvalidValueException("HKDF: bad key length"); } var prk = Hmac.nativeSha256(salt.size() > 0 ? salt : new [HASH_BYTES]b, ikm); var okm = new [0]b; var block = new [0]b; for (var counter = 1; okm.size() < length; counter++) { var input = Bytes.concat(block, info); input.add(counter); Bytes.wipe(block); block = Hmac.nativeSha256(prk, input); okm.addAll(block); } Bytes.wipe(prk); Bytes.wipe(block); var key = okm.slice(0, length); Bytes.wipe(okm); return key; } }