Skip to content

Commit

Permalink
Merge pull request #141 from dajiaji/support-sha384-over-hash-size-le…
Browse files Browse the repository at this point in the history
…ngth-key

Support over hash size length key for SHA384.
  • Loading branch information
dajiaji authored Jan 17, 2023
2 parents fa13682 + 380188f commit ba1ac22
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 29 deletions.
14 changes: 8 additions & 6 deletions src/kdfs/hkdf.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { hmac } from "hmac";
import { sha256 } from "sha256";
import { sha512 } from "sha512";
import { sha384, sha512 } from "sha512";

import type { KdfInterface } from "../interfaces/kdfInterface.ts";

import { Kdf } from "../identifiers.ts";
import { WebCrypto } from "../webCrypto.ts";

import * as consts from "../consts.ts";
import * as errors from "../errors.ts";

export class Hkdf extends WebCrypto implements KdfInterface {
public readonly id: Kdf = 0;
Expand Down Expand Up @@ -69,15 +68,18 @@ export class Hkdf extends WebCrypto implements KdfInterface {
new Uint8Array(salt),
new Uint8Array(ikm),
);
case "SHA-512":
case "SHA-384":
return hmac(
sha512,
sha384,
new Uint8Array(salt),
new Uint8Array(ikm),
);
default:
throw new errors.NotSupportedError(
`${this.algHash.hash} key length should be ${this.hashSize}.`,
// case "SHA-512":
return hmac(
sha512,
new Uint8Array(salt),
new Uint8Array(ikm),
);
}
}
Expand Down
92 changes: 75 additions & 17 deletions test/cipherSuite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ describe("CipherSuite", () => {
});
});

describe("A README example of Oblivious HTTP (HKDF-SHA512)", () => {
describe("A README example of Oblivious HTTP (HKDF-SHA384)", () => {
it("should work normally", async () => {
if (isDeno()) {
return;
Expand All @@ -1361,8 +1361,8 @@ describe("CipherSuite", () => {
const cryptoApi = await loadCrypto();

const suite = new CipherSuite({
kem: Kem.DhkemP521HkdfSha512,
kdf: Kdf.HkdfSha512,
kem: Kem.DhkemP384HkdfSha384,
kdf: Kdf.HkdfSha384,
aead: Aead.Aes256Gcm,
});
const rkp = await suite.generateKeyPair();
Expand Down Expand Up @@ -1437,30 +1437,88 @@ describe("CipherSuite", () => {
});
});

describe("kdfContext.extract/expand with unsupported key length", () => {
it("should throw NotSupportedError", async () => {
describe("A README example of Oblivious HTTP (HKDF-SHA512)", () => {
it("should work normally", async () => {
if (isDeno()) {
return;
}
const te = new TextEncoder();
const cryptoApi = await loadCrypto();

// setup
const suite = new CipherSuite({
kem: Kem.DhkemP384HkdfSha384,
kdf: Kdf.HkdfSha384,
kem: Kem.DhkemP521HkdfSha512,
kdf: Kdf.HkdfSha512,
aead: Aead.Aes256Gcm,
});
const rkp = await suite.generateKeyPair();

const kdf = await suite.kdfContext();
// The sender (OHTTP client) side:
const response = te.encode("This is the response.");
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});

const salt = new Uint8Array(48 + 32);
cryptoApi.getRandomValues(salt);
const secretS = await sender.export(
te.encode("message/bhttp response"),
suite.aeadKeySize,
);

const ikm = new Uint8Array(48);
cryptoApi.getRandomValues(ikm);
const responseNonce = new Uint8Array(suite.aeadKeySize);
cryptoApi.getRandomValues(responseNonce);
const saltS = concat(new Uint8Array(sender.enc), responseNonce);

// assert
await assertRejects(
() => kdf.extract(salt, ikm),
errors.NotSupportedError,
const kdfS = await suite.kdfContext();
const prkS = await kdfS.extract(saltS, new Uint8Array(secretS));
const keyS = await kdfS.expand(
prkS,
te.encode("key"),
suite.aeadKeySize,
);
const nonceS = await kdfS.expand(
prkS,
te.encode("nonce"),
suite.aeadNonceSize,
);

const aeadKeyS = await suite.createAeadKey(keyS);
const ct = await aeadKeyS.seal(nonceS, response, te.encode(""));
const encResponse = concat(responseNonce, new Uint8Array(ct));

// The recipient (OHTTP server) side:
const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey,
enc: sender.enc,
});

const secretR = await recipient.export(
te.encode("message/bhttp response"),
suite.aeadKeySize,
);

const saltR = concat(
new Uint8Array(sender.enc),
encResponse.slice(0, suite.aeadKeySize),
);
const kdfR = await suite.kdfContext();
const prkR = await kdfR.extract(
saltR,
new Uint8Array(secretR),
);
const keyR = await kdfR.expand(prkR, te.encode("key"), suite.aeadKeySize);
const nonceR = await kdfR.expand(
prkR,
te.encode("nonce"),
suite.aeadNonceSize,
);
const aeadKeyR = await suite.createAeadKey(keyR);
const pt = await aeadKeyR.open(
nonceR,
encResponse.slice(suite.aeadKeySize),
te.encode(""),
);

// pt === "This is the response."
assertEquals(response, new Uint8Array(pt));
});
});
});
13 changes: 7 additions & 6 deletions test/kdfContext.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertEquals, assertRejects } from "testing/asserts.ts";
import { assertEquals } from "testing/asserts.ts";

import { describe, it } from "testing/bdd.ts";

Expand All @@ -8,7 +8,6 @@ import { loadCrypto, loadSubtleCrypto } from "../src/webCrypto.ts";
import { i2Osp } from "../src/utils/misc.ts";

import * as consts from "../src/consts.ts";
import * as errors from "../src/errors.ts";

describe("extract/expand", () => {
describe("HKDF-SHA256 with valid parameters", () => {
Expand Down Expand Up @@ -115,8 +114,9 @@ describe("extract/expand", () => {
});
});

describe("HKDF-SHA384 with unsupported salt length", () => {
describe("HKDF-SHA384 with over Nh length of salt.", () => {
it("should return a proper instance", async () => {
const te = new TextEncoder();
const api = await loadSubtleCrypto();
const cryptoApi = await loadCrypto();
const suiteId = new Uint8Array(consts.SUITE_ID_HEADER_HPKE);
Expand All @@ -132,9 +132,10 @@ describe("extract/expand", () => {
cryptoApi.getRandomValues(ikm);

// assert
await assertRejects(
() => kdf.extract(salt, ikm),
errors.NotSupportedError,
const prk = await kdf.extract(salt, ikm);
assertEquals(
typeof await kdf.expand(prk, te.encode("key"), 16),
"object",
);
});
});
Expand Down

0 comments on commit ba1ac22

Please sign in to comment.