5 <title>WebCrypto Test Suite
</title>
6 <meta http-equiv=
"Content-Type" content=
"text/html;charset=utf-8" />
7 <link rel=
"stylesheet" href=
"./test_WebCrypto.css"/>
8 <script src=
"/tests/SimpleTest/SimpleTest.js"></script>
10 <!-- Utilities for manipulating ABVs -->
11 <script src=
"util.js"></script>
13 <!-- A simple wrapper around IndexedDB -->
14 <script src=
"simpledb.js"></script>
16 <!-- Test vectors drawn from the literature -->
17 <script src=
"./test-vectors.js"></script>
19 <!-- General testing framework -->
20 <script src=
"./test-array.js"></script>
22 <script>/* <![CDATA[*/
25 // -----------------------------------------------------------------------------
27 "Key wrap known answer, using AES-GCM",
32 iv
: tv
.key_wrap_known_answer
.wrapping_iv
,
37 function doImport(k
) {
39 return crypto
.subtle
.importKey("raw", tv
.key_wrap_known_answer
.key
,
40 alg
, true, ["encrypt", "decrypt"]);
44 return crypto
.subtle
.wrapKey("raw", key
, wrappingKey
, alg
);
47 crypto
.subtle
.importKey("raw", tv
.key_wrap_known_answer
.wrapping_key
,
48 alg
, false, ["wrapKey"])
49 .then(doImport
, error(that
))
50 .then(doWrap
, error(that
))
52 memcmp_complete(that
, tv
.key_wrap_known_answer
.wrapped_key
),
58 // -----------------------------------------------------------------------------
60 "Key wrap failing on non-extractable key",
65 iv
: tv
.key_wrap_known_answer
.wrapping_iv
,
70 function doImport(k
) {
72 return crypto
.subtle
.importKey("raw", tv
.key_wrap_known_answer
.key
,
73 alg
, false, ["encrypt", "decrypt"]);
77 return crypto
.subtle
.wrapKey("raw", key
, wrappingKey
, alg
);
80 crypto
.subtle
.importKey("raw", tv
.key_wrap_known_answer
.wrapping_key
,
81 alg
, false, ["wrapKey"])
82 .then(doImport
, error(that
))
83 .then(doWrap
, error(that
))
91 // -----------------------------------------------------------------------------
93 "Key unwrap known answer, using AES-GCM",
98 iv
: tv
.key_wrap_known_answer
.wrapping_iv
,
103 function doUnwrap(k
) {
105 return crypto
.subtle
.unwrapKey(
106 "raw", tv
.key_wrap_known_answer
.wrapped_key
,
108 "AES-GCM", true, ["encrypt", "decrypt"]
111 function doExport(k
) {
112 return crypto
.subtle
.exportKey("raw", k
);
115 crypto
.subtle
.importKey("raw", tv
.key_wrap_known_answer
.wrapping_key
,
116 alg
, false, ["unwrapKey"])
117 .then(doUnwrap
, error(that
))
118 .then(doExport
, error(that
))
120 memcmp_complete(that
, tv
.key_wrap_known_answer
.key
),
126 // -----------------------------------------------------------------------------
128 "Key wrap/unwrap round-trip, using RSA-OAEP",
137 iv
: tv
.aes_gcm_enc
.iv
,
138 additionalData
: tv
.aes_gcm_enc
.adata
,
143 function doWrap(keys
) {
144 var originalKey
= keys
[0];
145 var wrapKey
= keys
[1];
147 return crypto
.subtle
.wrapKey("raw", originalKey
, wrapKey
, oaep
);
149 function doUnwrap(wrappedKey
) {
150 return crypto
.subtle
.unwrapKey("raw", wrappedKey
, unwrapKey
, oaep
,
151 gcm
, false, ["encrypt"]);
153 function doEncrypt(aesKey
) {
154 return crypto
.subtle
.encrypt(gcm
, aesKey
, tv
.aes_gcm_enc
.data
);
159 // -> OAEP wrap key (public)
160 // -> OAEP unwrap key (private)
161 // 2. Wrap the HMAC key
164 // 5. Check HMAC value
166 crypto
.subtle
.importKey("raw", tv
.aes_gcm_enc
.key
, gcm
, true, ["encrypt"]),
167 crypto
.subtle
.importKey("spki", tv
.rsaoaep
.spki
, oaep
, true, ["wrapKey"]),
168 crypto
.subtle
.importKey("pkcs8", tv
.rsaoaep
.pkcs8
, oaep
, false, ["unwrapKey"]),
170 .then(doWrap
, error(that
))
171 .then(doUnwrap
, error(that
))
172 .then(doEncrypt
, error(that
))
174 memcmp_complete(that
, tv
.aes_gcm_enc
.result
),
180 // -----------------------------------------------------------------------------
182 "HMAC JWK wrap/unwrap round-trip, with AES-GCM",
185 var genAlg
= { name
: "HMAC", hash
: "SHA-384", length
: 512 };
186 var wrapAlg
= { name
: "AES-GCM", iv
: tv
.aes_gcm_enc
.iv
};
187 var wrapKey
, originalKey
, originalKeyJwk
;
189 function doExport(k
) {
190 return crypto
.subtle
.exportKey("jwk", k
);
193 return crypto
.subtle
.wrapKey("jwk", originalKey
, wrapKey
, wrapAlg
);
195 function doUnwrap(wrappedKey
) {
196 return crypto
.subtle
.unwrapKey("jwk", wrappedKey
, wrapKey
, wrapAlg
,
197 { name
: "HMAC", hash
: "SHA-384"},
198 true, ["sign", "verify"]);
202 crypto
.subtle
.importKey("jwk", tv
.aes_gcm_enc
.key_jwk
,
203 "AES-GCM", false, ["wrapKey", "unwrapKey"])
204 .then(function(x
) { wrapKey
= x
; }),
205 crypto
.subtle
.generateKey(genAlg
, true, ["sign", "verify"])
206 .then(function(x
) { originalKey
= x
; return x
; })
208 .then(function(x
) { originalKeyJwk
= x
; }),
214 complete(that
, function(x
) {
215 return exists(x
.k
) && x
.k
== originalKeyJwk
.k
;
222 // -----------------------------------------------------------------------------
224 "ECDSA private JWK wrap/unwrap round-trip, with AES-GCM",
227 var genAlg
= { name
: "ECDSA", namedCurve
: "P-256" };
228 var wrapAlg
= { name
: "AES-GCM", iv
: tv
.aes_gcm_enc
.iv
};
229 var wrapKey
, originalKey
, originalKeyJwk
;
231 function doExport(k
) {
232 return crypto
.subtle
.exportKey("jwk", k
);
235 return crypto
.subtle
.wrapKey("jwk", originalKey
, wrapKey
, wrapAlg
);
237 function doUnwrap(wrappedKey
) {
238 return crypto
.subtle
.unwrapKey("jwk", wrappedKey
, wrapKey
, wrapAlg
,
239 genAlg
, true, ["sign"]);
243 crypto
.subtle
.importKey("jwk", tv
.aes_gcm_enc
.key_jwk
,
244 "AES-GCM", false, ["wrapKey", "unwrapKey"])
245 .then(function(x
) { wrapKey
= x
; }),
246 crypto
.subtle
.generateKey(genAlg
, true, ["sign", "verify"])
247 .then(function(x
) { originalKey
= x
.privateKey
; return x
.privateKey
; })
249 .then(function(x
) { originalKeyJwk
= x
; }),
255 complete(that
, function(x
) {
256 return (x
.kty
== originalKeyJwk
.kty
) &&
257 (x
.crv
== originalKeyJwk
.crv
) &&
258 (x
.d
== originalKeyJwk
.d
) &&
259 (x
.x
== originalKeyJwk
.x
) &&
260 (x
.y
== originalKeyJwk
.y
);
267 // -----------------------------------------------------------------------------
269 "AES-KW known answer",
273 function doWrap(keys
) {
274 var wrapKey
= keys
[0];
275 var originalKey
= keys
[1];
276 return crypto
.subtle
.wrapKey("raw", originalKey
, wrapKey
, "AES-KW");
280 crypto
.subtle
.importKey("jwk", tv
.aes_kw
.wrapping_key
,
281 "AES-KW", false, ["wrapKey"]),
282 crypto
.subtle
.importKey("jwk", tv
.aes_kw
.key
,
283 "AES-GCM", true, ["encrypt"]),
287 memcmp_complete(that
, tv
.aes_kw
.wrapped_key
),
293 // -----------------------------------------------------------------------------
295 "AES-KW unwrap failure on tampered key data",
298 var tamperedWrappedKey
= new Uint8Array(tv
.aes_kw
.wrapped_key
);
299 tamperedWrappedKey
[5] ^= 0xFF;
301 function doUnwrap(wrapKey
) {
302 return crypto
.subtle
.unwrapKey("raw", tamperedWrappedKey
, wrapKey
,
304 true, ["encrypt", "decrypt"]);
307 crypto
.subtle
.importKey("jwk", tv
.aes_kw
.wrapping_key
,
308 "AES-KW", false, ["unwrapKey"])
310 .then(error(that
), complete(that
));
314 // -----------------------------------------------------------------------------
316 "AES-KW unwrap AES-KW key data",
319 var wrappedKey
= new Uint8Array(tv
.aes_kw
.wrapped_key
);
321 function doUnwrap(wrapKey
) {
322 return crypto
.subtle
.unwrapKey("raw", wrappedKey
, wrapKey
,
324 true, ["wrapKey", "unwrapKey"]);
327 crypto
.subtle
.importKey("jwk", tv
.aes_kw
.wrapping_key
,
328 "AES-KW", false, ["unwrapKey"])
331 memcmp_complete(that
, tv
.aes_kw
.key
),
337 // -----------------------------------------------------------------------------
339 "AES-KW wrap/unwrap round-trip",
342 var genAlg
= { name
: "HMAC", hash
: "SHA-384", length
: 512 };
343 var wrapKey
, originalKey
, originalKeyJwk
;
345 function doExport(k
) {
346 return crypto
.subtle
.exportKey("jwk", k
);
349 return crypto
.subtle
.wrapKey("raw", originalKey
, wrapKey
, "AES-KW");
351 function doUnwrap(wrappedKey
) {
352 return crypto
.subtle
.unwrapKey("raw", wrappedKey
, wrapKey
,
353 "AES-KW", { name
: "HMAC", hash
: "SHA-384"},
354 true, ["sign", "verify"]);
358 crypto
.subtle
.importKey("jwk", tv
.aes_kw
.wrapping_key
,
359 "AES-KW", false, ["wrapKey", "unwrapKey"])
360 .then(function(x
) { wrapKey
= x
; }),
361 crypto
.subtle
.generateKey(genAlg
, true, ["sign"])
362 .then(function(x
) { originalKey
= x
; return x
; })
364 .then(function(x
) { originalKeyJwk
= x
; }),
370 complete(that
, function(x
) {
371 return exists(x
.k
) && x
.k
== originalKeyJwk
.k
;
378 // -----------------------------------------------------------------------------
380 "JWK unwrap attempt on bogus data should error out",
382 // Largely cribbed from the "JWK wrap/unwrap round-trip, with AES-GCM" test
384 var wrapAlg
= { name
: "AES-GCM", iv
: tv
.aes_gcm_enc
.iv
};
387 function doBogusWrap() {
388 var abv
= new TextEncoder().encode("I am so not JSON");
389 return crypto
.subtle
.encrypt(wrapAlg
, wrapKey
, abv
);
391 function doUnwrap(wrappedKey
) {
392 return crypto
.subtle
.unwrapKey("jwk", wrappedKey
, wrapKey
, wrapAlg
,
393 {name
: "HMAC", hash
: "SHA-384"},
394 true, ["sign", "verify"]);
397 crypto
.subtle
.importKey("jwk", tv
.aes_gcm_enc
.key_jwk
,
398 "AES-GCM", false, ["encrypt", "unwrapKey"])
399 .then(function(x
) { wrapKey
= x
; })
400 .then(doBogusWrap
, error(that
))
401 .then(doUnwrap
, error(that
))
419 <div id=
"start" onclick=
"start();">RUN ALL
</div>
421 <div id=
"resultDiv" class=
"content">
423 <span class=
"pass"><span id=
"passN">0</span> passed,
</span>
424 <span class=
"fail"><span id=
"failN">0</span> failed,
</span>
425 <span class=
"pending"><span id=
"pendingN">0</span> pending.
</span>
439 <div id=
"foot"></div>