BlockCipher.js
3.7 KB
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { Cipher } from "./Cipher";
import { CBC } from "./mode/CBC";
import { Pkcs7 } from "./pad/Pkcs7";
export class BlockCipher extends Cipher {
constructor(props) {
super(props);
this._blockSize = 128 / 32;
this._Mode = CBC;
this._padding = Pkcs7;
this._props = props;
this._Mode = typeof props.mode !== "undefined" ? props.mode : this._Mode;
this._padding = typeof props.padding !== "undefined" ? props.padding : this._padding;
this.reset(props === null || props === void 0 ? void 0 : props.data, props === null || props === void 0 ? void 0 : props.nBytes);
}
get mode() {
return this._mode;
}
get padding() {
return this._padding;
}
reset(data, nBytes) {
super.reset(data, nBytes);
let modeCreator;
if (this._transformMode === Cipher.ENC_TRANSFORM_MODE) {
modeCreator = this._Mode.createEncryptor;
}
else {
modeCreator = this._Mode.createDecryptor;
// Keep at least one block in the buffer for unpadding
this._minBufferSize = 1;
}
if (this._Mode && this._modeCreator === modeCreator) {
this._mode = new this._Mode({ cipher: this, iv: this._iv });
}
else {
this._mode = modeCreator.call(this._Mode, { cipher: this, iv: this._iv });
this._modeCreator = modeCreator;
}
}
_doProcessBlock(words, offset) {
var _a;
(_a = this._mode) === null || _a === void 0 ? void 0 : _a.processBlock(words, offset);
}
_doFinalize() {
let finalProcessedBlocks;
// Shortcut
const padding = this._padding;
// Finalize
if (this._transformMode === Cipher.ENC_TRANSFORM_MODE) {
// Pad data
padding.pad(this._data, this.blockSize);
// Process final blocks
finalProcessedBlocks = this._process(true);
}
else /* if (this._transformMode == Cipher._DEC_TRANSFORM_MODE) */ {
// Process final blocks
finalProcessedBlocks = this._process(true);
// Unpad data
padding.unpad(finalProcessedBlocks);
}
return finalProcessedBlocks;
}
/**
* @abstract
*/
encryptBlock(words, offset) {
throw new Error("Not implemented");
}
/**
* @abstract
*/
decryptBlock(words, offset) {
throw new Error("Not implemented");
}
/**
* Creates this cipher in encryption mode.
*
* @param {Word32Array} key The key.
* @param {Partial<CipherProps>?} props (Optional) The configuration options to use for this operation.
* @return {Cipher} A cipher instance.
* @example
* var cipher = AES.createEncryptor(keyWordArray, { iv: ivWordArray });
*/
static createEncryptor(key, props) {
props = typeof props === "undefined" ? {} : props;
return new BlockCipher(Object.assign(Object.assign({}, props), { key, transformMode: Cipher.ENC_TRANSFORM_MODE }));
}
/**
* Creates this cipher in decryption mode.
* @param {Word32Array} key The key.
* @param {Partial<CipherProps>?} props (Optional) The configuration options to use for this operation.
* @return {Cipher} A cipher instance.
* @example
* var cipher = AES.createDecryptor(keyWordArray, { iv: ivWordArray });
*/
static createDecryptor(key, props) {
props = typeof props === "undefined" ? {} : props;
return new BlockCipher(Object.assign(Object.assign({}, props), { key, transformMode: Cipher.DEC_TRANSFORM_MODE }));
}
}