@hackbg/miscreant-esm
Version:
(ESM port) Misuse resistant symmetric encryption library providing AES-SIV (RFC 5297), AES-PMAC-SIV, and STREAM constructions
109 lines (108 loc) • 3.48 kB
JavaScript
;
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());
});
});
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.StreamDecryptor = exports.StreamEncryptor = exports.COUNTER_MAX = exports.LAST_BLOCK_FLAG = exports.NONCE_SIZE = void 0;
const aead_1 = require("./aead.dist.cjs");
const webcrypto_1 = require("./providers/webcrypto.dist.cjs");
exports.NONCE_SIZE = 8;
exports.LAST_BLOCK_FLAG = 1;
exports.COUNTER_MAX = 0xFFFFFFFF;
class StreamEncryptor {
static importKey(keyData, nonce, alg, provider = new webcrypto_1.WebCryptoProvider()) {
return __awaiter(this, void 0, void 0, function* () {
return new StreamEncryptor(yield aead_1.AEAD.importKey(keyData, alg, provider), nonce);
});
}
constructor(aead, nonce) {
this._aead = aead;
this._nonce_encoder = new NonceEncoder(nonce);
}
seal(plaintext, lastBlock = false, associatedData = new Uint8Array(0)) {
return __awaiter(this, void 0, void 0, function* () {
return this._aead.seal(plaintext, this._nonce_encoder.next(lastBlock), associatedData);
});
}
clear() {
this._aead.clear();
return this;
}
}
exports.StreamEncryptor = StreamEncryptor;
class StreamDecryptor {
static importKey(keyData, nonce, alg, provider = new webcrypto_1.WebCryptoProvider()) {
return __awaiter(this, void 0, void 0, function* () {
return new StreamDecryptor(yield aead_1.AEAD.importKey(keyData, alg, provider), nonce);
});
}
constructor(aead, nonce) {
this._aead = aead;
this._nonce_encoder = new NonceEncoder(nonce);
}
open(ciphertext, lastBlock = false, associatedData = new Uint8Array(0)) {
return __awaiter(this, void 0, void 0, function* () {
return this._aead.open(ciphertext, this._nonce_encoder.next(lastBlock), associatedData);
});
}
clear() {
this._aead.clear();
return this;
}
}
exports.StreamDecryptor = StreamDecryptor;
class NonceEncoder {
constructor(noncePrefix) {
if (noncePrefix.length !== exports.NONCE_SIZE) {
throw new Error(`STREAM: nonce must be 8-bits (got ${noncePrefix.length}`);
}
this.buffer = new ArrayBuffer(exports.NONCE_SIZE + 4 + 1);
this.view = new DataView(this.buffer);
this.array = new Uint8Array(this.buffer);
this.array.set(noncePrefix);
this.counter = 0;
this.finished = false;
}
next(lastBlock) {
if (this.finished) {
throw new Error("STREAM: already finished");
}
this.view.setInt32(8, this.counter, false);
if (lastBlock) {
this.view.setInt8(12, exports.LAST_BLOCK_FLAG);
this.finished = true;
} else {
this.counter += 1;
if (this.counter > exports.COUNTER_MAX) {
throw new Error("STREAM counter overflowed");
}
}
return this.array;
}
}