Skip to content

Commit 370baa4

Browse files
authored
Update: generate and apply header values when key wrapping (#189)
1 parent da9a9f2 commit 370baa4

File tree

9 files changed

+366
-269
lines changed

9 files changed

+366
-269
lines changed

lib/algorithms/aes-gcm.js

+47-14
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,43 @@
66
"use strict";
77

88
var helpers = require("./helpers.js"),
9+
util = require("../util"),
910
CONSTANTS = require("./constants.js"),
1011
GCM = require("../deps/ciphermodes/gcm");
1112

12-
function gcmEncryptFN(size) {
13+
function gcmEncryptFN(size, wrap) {
1314
function commonChecks(key, iv) {
1415
if (size !== (key.length << 3)) {
1516
throw new Error("invalid key size");
1617
}
17-
if (12 !== iv.length) {
18+
if (!iv && !wrap) {
19+
throw new Error("invalid iv");
20+
}
21+
if (iv && 12 !== iv.length) {
1822
throw new Error("invalid iv");
1923
}
2024
}
2125

26+
function prepareResults(results) {
27+
if (wrap) {
28+
var iv = util.base64url.encode(results.iv);
29+
var tag = util.base64url.encode(results.tag);
30+
31+
results = {
32+
data: results.data,
33+
header: {
34+
iv: iv,
35+
tag: tag
36+
}
37+
};
38+
}
39+
40+
return results;
41+
}
42+
2243
// ### 'fallback' implementation -- uses forge
2344
var fallback = function(key, pdata, props) {
24-
var iv = props.iv || Buffer.alloc(0),
45+
var iv = props.iv,
2546
adata = props.aad || props.adata || Buffer.alloc(0),
2647
cipher,
2748
cdata;
@@ -33,6 +54,8 @@ function gcmEncryptFN(size) {
3354
return Promise.reject(err);
3455
}
3556

57+
iv = iv || util.randomBytes(12);
58+
3659
// setup cipher
3760
cipher = GCM.createCipher({
3861
key: key,
@@ -69,10 +92,11 @@ function gcmEncryptFN(size) {
6992

7093
// resolve with output
7194
var tag = cipher.tag;
72-
resolve({
95+
resolve(prepareResults({
7396
data: cdata,
97+
iv: iv,
7498
tag: tag
75-
});
99+
}));
76100
})();
77101
});
78102

@@ -82,7 +106,7 @@ function gcmEncryptFN(size) {
82106
// ### WebCryptoAPI implementation
83107
// TODO: cache CryptoKey sooner
84108
var webcrypto = function(key, pdata, props) {
85-
var iv = props.iv || Buffer.alloc(0),
109+
var iv = props.iv,
86110
adata = props.aad || props.adata || Buffer.alloc(0);
87111

88112
try {
@@ -91,6 +115,8 @@ function gcmEncryptFN(size) {
91115
return Promise.reject(err);
92116
}
93117

118+
iv = iv || util.randomBytes(12);
119+
94120
var alg = {
95121
name: "AES-GCM"
96122
};
@@ -114,18 +140,19 @@ function gcmEncryptFN(size) {
114140
var cdata = result.slice(0, tagStart);
115141
cdata = Buffer.from(cdata);
116142

117-
return {
143+
return prepareResults({
118144
data: cdata,
145+
iv: iv,
119146
tag: tag
120-
};
147+
});
121148
});
122149

123150
return promise;
124151
};
125152

126153
// ### NodeJS implementation
127154
var nodejs = function(key, pdata, props) {
128-
var iv = props.iv || Buffer.alloc(0),
155+
var iv = props.iv,
129156
adata = props.aad || props.adata || Buffer.alloc(0);
130157

131158
try {
@@ -134,6 +161,8 @@ function gcmEncryptFN(size) {
134161
return Promise.reject(err);
135162
}
136163

164+
iv = iv || util.randomBytes(12);
165+
137166
var alg = "aes-" + (key.length * 8) + "-gcm";
138167
var cipher;
139168
try {
@@ -154,14 +183,16 @@ function gcmEncryptFN(size) {
154183
]);
155184
var tag = cipher.getAuthTag();
156185

157-
return {
186+
return prepareResults({
158187
data: cdata,
188+
iv: iv,
159189
tag: tag
160-
};
190+
});
161191
};
162192

163193
return helpers.setupFallback(nodejs, webcrypto, fallback);
164194
}
195+
165196
function gcmDecryptFN(size) {
166197
function commonChecks(key, iv, tag) {
167198
if (size !== (key.length << 3)) {
@@ -331,10 +362,12 @@ var aesGcm = {};
331362
"A192GCMKW",
332363
"A256GCMKW"
333364
].forEach(function(alg) {
334-
var size = parseInt(/A(\d+)GCM(?:KW)?/g.exec(alg)[1]);
365+
var parts = /A(\d+)GCM(KW)?/g.exec(alg);
366+
var size = parseInt(parts[1]);
367+
var wrap = (parts[2] === "KW");
335368
aesGcm[alg] = {
336-
encrypt: gcmEncryptFN(size),
337-
decrypt: gcmDecryptFN(size)
369+
encrypt: gcmEncryptFN(size, wrap),
370+
decrypt: gcmDecryptFN(size, wrap)
338371
};
339372
});
340373

0 commit comments

Comments
 (0)