tink-crypto
Version:
A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.
116 lines • 14.4 kB
JavaScript
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { SecurityException } from '../../../exception/security_exception';
import { fromRawKey as hmacFromRawKey } from '../../../subtle/hmac';
import * as validators from '../../../subtle/validators';
import * as hpkeUtil from './hpke_util';
/**
* HKDF HPKE KDF variant.
* @see https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1-3
*/
export class HkdfHpkeKdf {
constructor(hashFunction) {
this.hashFunction = hashFunction;
}
labeledExtract({ ikm, ikmLabel, suiteId, salt }) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.extract(hpkeUtil.labelIkm({ ikmLabel, ikm, suiteId }), salt);
});
}
labeledExpand({ prk, info, infoLabel, suiteId, length }) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.expand(prk, hpkeUtil.labelInfo({ infoLabel, info, suiteId, length }), length);
});
}
extractAndExpand({ ikm, ikmLabel, info, infoLabel, suiteId, length, salt }) {
return __awaiter(this, void 0, void 0, function* () {
const prk = yield this.extract(hpkeUtil.labelIkm({ ikmLabel, ikm, suiteId }), salt);
return yield this.expand(prk, hpkeUtil.labelInfo({ infoLabel, info, suiteId, length }), length);
});
}
/**
* Copied from `javascript/subtle/hkdf`'s `compute` function
*/
expand(prk, info, length) {
return __awaiter(this, void 0, void 0, function* () {
if (!Number.isInteger(length)) {
throw new SecurityException('length must be an integer');
}
if (length <= 0) {
throw new SecurityException('length must be positive');
}
const digestSize = this.getMacLength();
if (length > 255 * digestSize) {
throw new SecurityException('length too large');
}
validators.requireUint8Array(info);
const hmac = yield hmacFromRawKey(this.hashFunction, prk, digestSize);
let ctr = 1;
let pos = 0;
let digest = new Uint8Array(0);
const result = new Uint8Array(length);
while (true) {
const input = new Uint8Array(digest.length + info.length + 1);
input.set(digest, 0);
input.set(info, digest.length);
input[input.length - 1] = ctr;
digest = yield hmac.computeMac(input);
if (pos + digest.length < length) {
result.set(digest, pos);
pos += digest.length;
ctr++;
}
else {
result.set(digest.subarray(0, length - pos), pos);
break;
}
}
return result;
});
}
/**
* Copied from `javascript/subtle/hkdf`'s `compute` function
*/
extract(ikm, salt) {
return __awaiter(this, void 0, void 0, function* () {
validators.requireUint8Array(ikm);
const digestSize = this.getMacLength();
if (!(salt === null || salt === void 0 ? void 0 : salt.length)) {
salt = new Uint8Array(digestSize);
}
validators.requireUint8Array(salt);
const hmac = yield hmacFromRawKey(this.hashFunction, salt, digestSize);
const prk = yield hmac.computeMac(ikm);
return prk;
});
}
getKdfId() {
switch (this.hashFunction) {
case 'SHA-256':
return hpkeUtil.HKDF_SHA256_KDF_ID;
case 'SHA-512':
return hpkeUtil.HKDF_SHA512_KDF_ID;
}
}
getMacLength() {
switch (this.hashFunction) {
case 'SHA-256':
return 32;
case 'SHA-512':
return 64;
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGtkZl9ocGtlX2tkZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2h5YnJpZC9pbnRlcm5hbC9ocGtlL2hrZGZfaHBrZV9rZGYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRzs7Ozs7Ozs7OztBQUVILE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHVDQUF1QyxDQUFDO0FBQ3hFLE9BQU8sRUFBQyxVQUFVLElBQUksY0FBYyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDbEUsT0FBTyxLQUFLLFVBQVUsTUFBTSw0QkFBNEIsQ0FBQztBQUd6RCxPQUFPLEtBQUssUUFBUSxNQUFNLGFBQWEsQ0FBQztBQUV4Qzs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sV0FBVztJQUN0QixZQUE2QixZQUFpQztRQUFqQyxpQkFBWSxHQUFaLFlBQVksQ0FBcUI7SUFBRyxDQUFDO0lBRTVELGNBQWMsQ0FBQyxFQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFLakQ7O1lBQ0MsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQ3JCLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDekQsQ0FBQztLQUFBO0lBRUssYUFBYSxDQUFDLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFNekQ7O1lBQ0MsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQ3BCLEdBQUcsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzRSxDQUFDO0tBQUE7SUFFSyxnQkFBZ0IsQ0FDbEIsRUFBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLElBQUksRUFB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Q0FBQyxDQUFBLElBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxNQUFNLENBQUEsRUFBRTtnQkFDakIsSUFBSSxHQUFHLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ25DO1lBQ0QsVUFBVSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBRW5DLE1BQU0sSUFBSSxHQUFHLE1BQU0sY0FBYyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3ZFLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUV2QyxPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7S0FBQTtJQUVELFFBQVE7UUFDTixRQUFRLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDekIsS0FBSyxTQUFTO2dCQUNaLE9BQU8sUUFBUSxDQUFDLGtCQUFrQixDQUFDO1lBQ3JDLEtBQUssU0FBUztnQkFDWixPQUFPLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztTQUN0QztJQUNILENBQUM7SUFFRCxZQUFZO1FBQ1YsUUFBUSxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ3pCLEtBQUssU0FBUztnQkFDWixPQUFPLEVBQUUsQ0FBQztZQUNaLEtBQUssU0FBUztnQkFDWixPQUFPLEVBQUUsQ0FBQztTQUNiO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuXG5pbXBvcnQge1NlY3VyaXR5RXhjZXB0aW9ufSBmcm9tICcuLi8uLi8uLi9leGNlcHRpb24vc2VjdXJpdHlfZXhjZXB0aW9uJztcbmltcG9ydCB7ZnJvbVJhd0tleSBhcyBobWFjRnJvbVJhd0tleX0gZnJvbSAnLi4vLi4vLi4vc3VidGxlL2htYWMnO1xuaW1wb3J0ICogYXMgdmFsaWRhdG9ycyBmcm9tICcuLi8uLi8uLi9zdWJ0bGUvdmFsaWRhdG9ycyc7XG5cbmltcG9ydCB7SHBrZUtkZn0gZnJvbSAnLi9ocGtlX2tkZic7XG5pbXBvcnQgKiBhcyBocGtlVXRpbCBmcm9tICcuL2hwa2VfdXRpbCc7XG5cbi8qKlxuICogSEtERiBIUEtFIEtERiB2YXJpYW50LlxuICogQHNlZSBodHRwczovL3d3dy5yZmMtZWRpdG9yLm9yZy9yZmMvcmZjOTE4MC5odG1sI3NlY3Rpb24tNC4xLTNcbiAqL1xuZXhwb3J0IGNsYXNzIEhrZGZIcGtlS2RmIGltcGxlbWVudHMgSHBrZUtkZiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgaGFzaEZ1bmN0aW9uOiAnU0hBLTI1Nid8J1NIQS01MTInKSB7fVxuXG4gIGFzeW5jIGxhYmVsZWRFeHRyYWN0KHtpa20sIGlrbUxhYmVsLCBzdWl0ZUlkLCBzYWx0fToge1xuICAgIGlrbTogVWludDhBcnJheSxcbiAgICBpa21MYWJlbDogc3RyaW5nLFxuICAgIHN1aXRlSWQ6IFVpbnQ4QXJyYXksXG4gICAgc2FsdD86IFVpbnQ4QXJyYXlcbiAgfSk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmV4dHJhY3QoXG4gICAgICAgIGhwa2VVdGlsLmxhYmVsSWttKHtpa21MYWJlbCwgaWttLCBzdWl0ZUlkfSksIHNhbHQpO1xuICB9XG5cbiAgYXN5bmMgbGFiZWxlZEV4cGFuZCh7cHJrLCBpbmZvLCBpbmZvTGFiZWwsIHN1aXRlSWQsIGxlbmd0aH06IHtcbiAgICBwcms6IFVpbnQ4QXJyYXksXG4gICAgaW5mbzogVWludDhBcnJheSxcbiAgICBpbmZvTGFiZWw6IHN0cmluZyxcbiAgICBzdWl0ZUlkOiBVaW50OEFycmF5LFxuICAgIGxlbmd0aDogbnVtYmVyXG4gIH0pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5leHBhbmQoXG4gICAgICAgIHByaywgaHBrZVV0aWwubGFiZWxJbmZvKHtpbmZvTGFiZWwsIGluZm8sIHN1aXRlSWQsIGxlbmd0aH0pLCBsZW5ndGgpO1xuICB9XG5cbiAgYXN5bmMgZXh0cmFjdEFuZEV4cGFuZChcbiAgICAgIHtpa20sIGlrbUxhYmVsLCBpbmZvLCBpbmZvTGFiZWwsIHN1aXRlSWQsIGxlbmd0aCwgc2FsdH06IHtcbiAgICAgICAgaWttOiBVaW50OEFycmF5LFxuICAgICAgICBpa21MYWJlbDogc3RyaW5nLFxuICAgICAgICBpbmZvOiBVaW50OEFycmF5LFxuICAgICAgICBpbmZvTGFiZWw6IHN0cmluZyxcbiAgICAgICAgc3VpdGVJZDogVWludDhBcnJheSxcbiAgICAgICAgbGVuZ3RoOiBudW1iZXIsXG4gICAgICAgIHNhbHQ/OiBVaW50OEFycmF5XG4gICAgICB9KTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gICAgY29uc3QgcHJrOiBVaW50OEFycmF5ID1cbiAgICAgICAgYXdhaXQgdGhpcy5leHRyYWN0KGhwa2VVdGlsLmxhYmVsSWttKHtpa21MYWJlbCwgaWttLCBzdWl0ZUlkfSksIHNhbHQpO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmV4cGFuZChcbiAgICAgICAgcHJrLCBocGtlVXRpbC5sYWJlbEluZm8oe2luZm9MYWJlbCwgaW5mbywgc3VpdGVJZCwgbGVuZ3RofSksIGxlbmd0aCk7XG4gIH1cblxuICAvKipcbiAgICogQ29waWVkIGZyb20gYGphdmFzY3JpcHQvc3VidGxlL2hrZGZgJ3MgYGNvbXB1dGVgIGZ1bmN0aW9uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4cGFuZChwcms6IFVpbnQ4QXJyYXksIGluZm86IFVpbnQ4QXJyYXksIGxlbmd0aDogbnVtYmVyKTpcbiAgICAgIFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihsZW5ndGgpKSB7XG4gICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oJ2xlbmd0aCBtdXN0IGJlIGFuIGludGVnZXInKTtcbiAgICB9XG4gICAgaWYgKGxlbmd0aCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oJ2xlbmd0aCBtdXN0IGJlIHBvc2l0aXZlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGlnZXN0U2l6ZSA9IHRoaXMuZ2V0TWFjTGVuZ3RoKCk7XG5cbiAgICBpZiAobGVuZ3RoID4gMjU1ICogZGlnZXN0U2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCdsZW5ndGggdG9vIGxhcmdlJyk7XG4gICAgfVxuICAgIHZhbGlkYXRvcnMucmVxdWlyZVVpbnQ4QXJyYXkoaW5mbyk7XG5cbiAgICBjb25zdCBobWFjID0gYXdhaXQgaG1hY0Zyb21SYXdLZXkodGhpcy5oYXNoRnVuY3Rpb24sIHByaywgZGlnZXN0U2l6ZSk7XG4gICAgbGV0IGN0ciA9IDE7XG4gICAgbGV0IHBvcyA9IDA7XG4gICAgbGV0IGRpZ2VzdCA9IG5ldyBVaW50OEFycmF5KDApO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGxlbmd0aCk7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IGlucHV0ID0gbmV3IFVpbnQ4QXJyYXkoZGlnZXN0Lmxlbmd0aCArIGluZm8ubGVuZ3RoICsgMSk7XG4gICAgICBpbnB1dC5zZXQoZGlnZXN0LCAwKTtcbiAgICAgIGlucHV0LnNldChpbmZvLCBkaWdlc3QubGVuZ3RoKTtcbiAgICAgIGlucHV0W2lucHV0Lmxlbmd0aCAtIDFdID0gY3RyO1xuICAgICAgZGlnZXN0ID0gYXdhaXQgaG1hYy5jb21wdXRlTWFjKGlucHV0KTtcbiAgICAgIGlmIChwb3MgKyBkaWdlc3QubGVuZ3RoIDwgbGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdC5zZXQoZGlnZXN0LCBwb3MpO1xuICAgICAgICBwb3MgKz0gZGlnZXN0Lmxlbmd0aDtcbiAgICAgICAgY3RyKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQuc2V0KGRpZ2VzdC5zdWJhcnJheSgwLCBsZW5ndGggLSBwb3MpLCBwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3BpZWQgZnJvbSBgamF2YXNjcmlwdC9zdWJ0bGUvaGtkZmAncyBgY29tcHV0ZWAgZnVuY3Rpb25cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZXh0cmFjdChpa206IFVpbnQ4QXJyYXksIHNhbHQ/OiBVaW50OEFycmF5KTpcbiAgICAgIFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIHZhbGlkYXRvcnMucmVxdWlyZVVpbnQ4QXJyYXkoaWttKTtcbiAgICBjb25zdCBkaWdlc3RTaXplID0gdGhpcy5nZXRNYWNMZW5ndGgoKTtcbiAgICBpZiAoIXNhbHQ/Lmxlbmd0aCkge1xuICAgICAgc2FsdCA9IG5ldyBVaW50OEFycmF5KGRpZ2VzdFNpemUpO1xuICAgIH1cbiAgICB2YWxpZGF0b3JzLnJlcXVpcmVVaW50OEFycmF5KHNhbHQpO1xuXG4gICAgY29uc3QgaG1hYyA9IGF3YWl0IGhtYWNGcm9tUmF3S2V5KHRoaXMuaGFzaEZ1bmN0aW9uLCBzYWx0LCBkaWdlc3RTaXplKTtcbiAgICBjb25zdCBwcmsgPSBhd2FpdCBobWFjLmNvbXB1dGVNYWMoaWttKTtcblxuICAgIHJldHVybiBwcms7XG4gIH1cblxuICBnZXRLZGZJZCgpOiBVaW50OEFycmF5IHtcbiAgICBzd2l0Y2ggKHRoaXMuaGFzaEZ1bmN0aW9uKSB7XG4gICAgICBjYXNlICdTSEEtMjU2JzpcbiAgICAgICAgcmV0dXJuIGhwa2VVdGlsLkhLREZfU0hBMjU2X0tERl9JRDtcbiAgICAgIGNhc2UgJ1NIQS01MTInOlxuICAgICAgICByZXR1cm4gaHBrZVV0aWwuSEtERl9TSEE1MTJfS0RGX0lEO1xuICAgIH1cbiAgfVxuXG4gIGdldE1hY0xlbmd0aCgpOiBudW1iZXIge1xuICAgIHN3aXRjaCAodGhpcy5oYXNoRnVuY3Rpb24pIHtcbiAgICAgIGNhc2UgJ1NIQS0yNTYnOlxuICAgICAgICByZXR1cm4gMzI7XG4gICAgICBjYXNlICdTSEEtNTEyJzpcbiAgICAgICAgcmV0dXJuIDY0O1xuICAgIH1cbiAgfVxufVxuIl19