blob: 97814b9967ae792ff3f9c5f5de3a762388522bcb (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
// 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;
}
}
|