@metamask-previews/cryptography 1.0.0-preview-9e306636a → 1.1.0-preview-c2be02bd4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -9,6 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Fixed
11
11
 
12
+ - Export AES-GCM IV length ([#10654](https://github.com/MetaMask/core/pull/10654))
13
+
14
+ ## [1.1.0]
15
+
16
+ ### Added
17
+
18
+ - Add an `additionalData` option to AES-GCM `encrypt` and `decrypt` ([#10628](https://github.com/MetaMask/core/pull/10628))
19
+ - Allow HKDF functions to derive from an empty input when `unsafeInputKeyingMaterial` is set ([#10628](https://github.com/MetaMask/core/pull/10628))
20
+
21
+ ### Fixed
22
+
12
23
  - Narrow return type for AES `encrypt` function to `Uint8Array<ArrayBuffer>` ([#10623](https://github.com/MetaMask/core/pull/10623))
13
24
 
14
25
  ## [1.0.0]
@@ -25,5 +36,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
25
36
  - Add `encrypt` and `decrypt` functions for AES-GCM symmetric encryption exported via `@metamask/cryptography/aes-gcm`
26
37
  - Add `getRandomBytes` function for generating cryptographically secure random bytes
27
38
 
28
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/cryptography@1.0.0...HEAD
39
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/cryptography@1.1.0...HEAD
40
+ [1.1.0]: https://github.com/MetaMask/core/compare/@metamask/cryptography@1.0.0...@metamask/cryptography@1.1.0
29
41
  [1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/cryptography@1.0.0
package/dist/aes-gcm.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export declare const IV_LENGTH = 12;
1
2
  export type AesGcmEncryptOptions = {
2
3
  /**
3
4
  * The initialization vector. If not provided, a random 12-byte IV
@@ -7,6 +8,11 @@ export type AesGcmEncryptOptions = {
7
8
  unsafeIv?: BufferSource;
8
9
  } & AesGcmDecryptOptions;
9
10
  export type AesGcmDecryptOptions = {
11
+ /**
12
+ * Associated data authenticated with the ciphertext but not encrypted.
13
+ * Encryption and decryption must use the same value.
14
+ */
15
+ additionalData?: BufferSource;
10
16
  /**
11
17
  * Skip the IV length check. Using an IV other than 12 bytes deviates from
12
18
  * the standard and is considered less safe.
@@ -1 +1 @@
1
- {"version":3,"file":"aes-gcm.d.ts","sourceRoot":"","sources":["../src/aes-gcm.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,GAAG,oBAAoB,CAAC;AAEzB,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACpC,EAAE,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;CAC7B,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,YAAY,EACvB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAuC9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,YAAY,EACjB,EAAE,EAAE,YAAY,EAChB,UAAU,EAAE,YAAY,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAmClC"}
1
+ {"version":3,"file":"aes-gcm.d.ts","sourceRoot":"","sources":["../src/aes-gcm.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,GAAG,oBAAoB,CAAC;AAEzB,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,cAAc,CAAC,EAAE,YAAY,CAAC;IAE9B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACpC,EAAE,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;CAC7B,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,YAAY,EACvB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA0C9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,YAAY,EACjB,EAAE,EAAE,YAAY,EAChB,UAAU,EAAE,YAAY,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAwClC"}
package/dist/aes-gcm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { getRandomBytes } from './random.js';
2
2
  import { toUint8Array } from './utils.js';
3
3
  // https://www.rfc-editor.org/rfc/rfc5116#section-5.1
4
- const AES_GCM_IV_LENGTH = 12;
4
+ export const IV_LENGTH = 12;
5
5
  /**
6
6
  * Encrypt data using AES-GCM.
7
7
  *
@@ -14,17 +14,21 @@ export async function encrypt(key, plaintext, options) {
14
14
  if (key.byteLength === 0) {
15
15
  throw new Error('Invalid key length: Key must not be zero bytes for AES-GCM.');
16
16
  }
17
- const iv = toUint8Array(options?.unsafeIv ?? getRandomBytes(AES_GCM_IV_LENGTH));
17
+ const iv = toUint8Array(options?.unsafeIv ?? getRandomBytes(IV_LENGTH));
18
18
  if (iv.byteLength === 0) {
19
19
  throw new Error('Invalid IV length: IV must not be zero bytes for AES-GCM.');
20
20
  }
21
- if (!options?.unsafeIvLength && iv.byteLength !== AES_GCM_IV_LENGTH) {
22
- throw new Error(`Unsafe IV length: IV must be exactly ${AES_GCM_IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \`unsafeIvLength\` option to \`true\`.`);
21
+ if (!options?.unsafeIvLength && iv.byteLength !== IV_LENGTH) {
22
+ throw new Error(`Unsafe IV length: IV must be exactly ${IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \`unsafeIvLength\` option to \`true\`.`);
23
23
  }
24
24
  const subtleKey = await globalThis.crypto.subtle.importKey('raw', key, { name: 'AES-GCM' }, false, ['encrypt']);
25
25
  const ciphertext = await globalThis.crypto.subtle.encrypt(
26
26
  // Converting to Uint8Array to work around a Node 22 bug, we may be able to remove in the future.
27
- { name: 'AES-GCM', iv }, subtleKey, toUint8Array(plaintext));
27
+ {
28
+ name: 'AES-GCM',
29
+ iv,
30
+ additionalData: options?.additionalData && toUint8Array(options.additionalData),
31
+ }, subtleKey, toUint8Array(plaintext));
28
32
  return { ciphertext: new Uint8Array(ciphertext), iv };
29
33
  }
30
34
  /**
@@ -43,13 +47,17 @@ export async function decrypt(key, iv, ciphertext, options) {
43
47
  if (iv.byteLength === 0) {
44
48
  throw new Error('Invalid IV length: IV must not be zero bytes for AES-GCM.');
45
49
  }
46
- if (!options?.unsafeIvLength && iv.byteLength !== AES_GCM_IV_LENGTH) {
47
- throw new Error(`Unsafe IV length: IV must be exactly ${AES_GCM_IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \`unsafeIvLength\` option to \`true\`.`);
50
+ if (!options?.unsafeIvLength && iv.byteLength !== IV_LENGTH) {
51
+ throw new Error(`Unsafe IV length: IV must be exactly ${IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \`unsafeIvLength\` option to \`true\`.`);
48
52
  }
49
53
  const subtleKey = await globalThis.crypto.subtle.importKey('raw', key, { name: 'AES-GCM' }, false, ['decrypt']);
50
54
  const plaintext = await globalThis.crypto.subtle.decrypt(
51
55
  // Converting to Uint8Array to work around a Node 22 bug, we may be able to remove in the future.
52
- { name: 'AES-GCM', iv: toUint8Array(iv) }, subtleKey, toUint8Array(ciphertext));
56
+ {
57
+ name: 'AES-GCM',
58
+ iv: toUint8Array(iv),
59
+ additionalData: options?.additionalData && toUint8Array(options.additionalData),
60
+ }, subtleKey, toUint8Array(ciphertext));
53
61
  return new Uint8Array(plaintext);
54
62
  }
55
63
  //# sourceMappingURL=aes-gcm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"aes-gcm.js","sourceRoot":"","sources":["../src/aes-gcm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,qDAAqD;AACrD,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAwB7B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAiB,EACjB,SAAuB,EACvB,OAA8B;IAE9B,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,YAAY,CACrB,OAAO,EAAE,QAAQ,IAAI,cAAc,CAAC,iBAAiB,CAAC,CACvD,CAAC;IAEF,IAAI,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,cAAc,IAAI,EAAE,CAAC,UAAU,KAAK,iBAAiB,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CACb,wCAAwC,iBAAiB,0FAA0F,CACpJ,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACxD,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,SAAS,EAAE,EACnB,KAAK,EACL,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO;IACvD,iGAAiG;IACjG,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EACvB,SAAS,EACT,YAAY,CAAC,SAAS,CAAC,CACxB,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAiB,EACjB,EAAgB,EAChB,UAAwB,EACxB,OAA8B;IAE9B,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,IAAI,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,cAAc,IAAI,EAAE,CAAC,UAAU,KAAK,iBAAiB,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CACb,wCAAwC,iBAAiB,0FAA0F,CACpJ,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACxD,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,SAAS,EAAE,EACnB,KAAK,EACL,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO;IACtD,iGAAiG;IACjG,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,EACzC,SAAS,EACT,YAAY,CAAC,UAAU,CAAC,CACzB,CAAC;IAEF,OAAO,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC","sourcesContent":["import { getRandomBytes } from './random.js';\nimport { toUint8Array } from './utils.js';\n\n// https://www.rfc-editor.org/rfc/rfc5116#section-5.1\nconst AES_GCM_IV_LENGTH = 12;\n\nexport type AesGcmEncryptOptions = {\n /**\n * The initialization vector. If not provided, a random 12-byte IV\n * is generated automatically. It is recommended to use the generated one rather\n * than providing one, to avoid IV reuse.\n */\n unsafeIv?: BufferSource;\n} & AesGcmDecryptOptions;\n\nexport type AesGcmDecryptOptions = {\n /**\n * Skip the IV length check. Using an IV other than 12 bytes deviates from\n * the standard and is considered less safe.\n */\n unsafeIvLength?: boolean;\n};\n\nexport type AesGcmEncryptResult = {\n ciphertext: Uint8Array<ArrayBuffer>;\n iv: Uint8Array<ArrayBuffer>;\n};\n\n/**\n * Encrypt data using AES-GCM.\n *\n * @param key - The 16, 24, or 32-byte AES key.\n * @param plaintext - The plaintext.\n * @param options - Additional configuration options.\n * @returns The ciphertext and the IV used for encryption.\n */\nexport async function encrypt(\n key: BufferSource,\n plaintext: BufferSource,\n options?: AesGcmEncryptOptions,\n): Promise<AesGcmEncryptResult> {\n if (key.byteLength === 0) {\n throw new Error(\n 'Invalid key length: Key must not be zero bytes for AES-GCM.',\n );\n }\n\n const iv = toUint8Array(\n options?.unsafeIv ?? getRandomBytes(AES_GCM_IV_LENGTH),\n );\n\n if (iv.byteLength === 0) {\n throw new Error(\n 'Invalid IV length: IV must not be zero bytes for AES-GCM.',\n );\n }\n\n if (!options?.unsafeIvLength && iv.byteLength !== AES_GCM_IV_LENGTH) {\n throw new Error(\n `Unsafe IV length: IV must be exactly ${AES_GCM_IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \\`unsafeIvLength\\` option to \\`true\\`.`,\n );\n }\n\n const subtleKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n key,\n { name: 'AES-GCM' },\n false,\n ['encrypt'],\n );\n\n const ciphertext = await globalThis.crypto.subtle.encrypt(\n // Converting to Uint8Array to work around a Node 22 bug, we may be able to remove in the future.\n { name: 'AES-GCM', iv },\n subtleKey,\n toUint8Array(plaintext),\n );\n\n return { ciphertext: new Uint8Array(ciphertext), iv };\n}\n\n/**\n * Decrypt data using AES-GCM.\n *\n * @param key - The 16, 24, or 32-byte AES key.\n * @param iv - The initialization vector.\n * @param ciphertext - The ciphertext.\n * @param options - Additional configuration options.\n * @returns The decrypted plaintext.\n */\nexport async function decrypt(\n key: BufferSource,\n iv: BufferSource,\n ciphertext: BufferSource,\n options?: AesGcmDecryptOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n if (key.byteLength === 0) {\n throw new Error(\n 'Invalid key length: Key must not be zero bytes for AES-GCM.',\n );\n }\n\n if (iv.byteLength === 0) {\n throw new Error(\n 'Invalid IV length: IV must not be zero bytes for AES-GCM.',\n );\n }\n\n if (!options?.unsafeIvLength && iv.byteLength !== AES_GCM_IV_LENGTH) {\n throw new Error(\n `Unsafe IV length: IV must be exactly ${AES_GCM_IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \\`unsafeIvLength\\` option to \\`true\\`.`,\n );\n }\n\n const subtleKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n key,\n { name: 'AES-GCM' },\n false,\n ['decrypt'],\n );\n\n const plaintext = await globalThis.crypto.subtle.decrypt(\n // Converting to Uint8Array to work around a Node 22 bug, we may be able to remove in the future.\n { name: 'AES-GCM', iv: toUint8Array(iv) },\n subtleKey,\n toUint8Array(ciphertext),\n );\n\n return new Uint8Array(plaintext);\n}\n"]}
1
+ {"version":3,"file":"aes-gcm.js","sourceRoot":"","sources":["../src/aes-gcm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,qDAAqD;AACrD,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AA8B5B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAiB,EACjB,SAAuB,EACvB,OAA8B;IAE9B,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IAExE,IAAI,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,cAAc,IAAI,EAAE,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,wCAAwC,SAAS,0FAA0F,CAC5I,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACxD,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,SAAS,EAAE,EACnB,KAAK,EACL,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO;IACvD,iGAAiG;IACjG;QACE,IAAI,EAAE,SAAS;QACf,EAAE;QACF,cAAc,EACZ,OAAO,EAAE,cAAc,IAAI,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC;KAClE,EACD,SAAS,EACT,YAAY,CAAC,SAAS,CAAC,CACxB,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAiB,EACjB,EAAgB,EAChB,UAAwB,EACxB,OAA8B;IAE9B,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,IAAI,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,cAAc,IAAI,EAAE,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,wCAAwC,SAAS,0FAA0F,CAC5I,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACxD,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,SAAS,EAAE,EACnB,KAAK,EACL,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO;IACtD,iGAAiG;IACjG;QACE,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC;QACpB,cAAc,EACZ,OAAO,EAAE,cAAc,IAAI,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC;KAClE,EACD,SAAS,EACT,YAAY,CAAC,UAAU,CAAC,CACzB,CAAC;IAEF,OAAO,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC","sourcesContent":["import { getRandomBytes } from './random.js';\nimport { toUint8Array } from './utils.js';\n\n// https://www.rfc-editor.org/rfc/rfc5116#section-5.1\nexport const IV_LENGTH = 12;\n\nexport type AesGcmEncryptOptions = {\n /**\n * The initialization vector. If not provided, a random 12-byte IV\n * is generated automatically. It is recommended to use the generated one rather\n * than providing one, to avoid IV reuse.\n */\n unsafeIv?: BufferSource;\n} & AesGcmDecryptOptions;\n\nexport type AesGcmDecryptOptions = {\n /**\n * Associated data authenticated with the ciphertext but not encrypted.\n * Encryption and decryption must use the same value.\n */\n additionalData?: BufferSource;\n\n /**\n * Skip the IV length check. Using an IV other than 12 bytes deviates from\n * the standard and is considered less safe.\n */\n unsafeIvLength?: boolean;\n};\n\nexport type AesGcmEncryptResult = {\n ciphertext: Uint8Array<ArrayBuffer>;\n iv: Uint8Array<ArrayBuffer>;\n};\n\n/**\n * Encrypt data using AES-GCM.\n *\n * @param key - The 16, 24, or 32-byte AES key.\n * @param plaintext - The plaintext.\n * @param options - Additional configuration options.\n * @returns The ciphertext and the IV used for encryption.\n */\nexport async function encrypt(\n key: BufferSource,\n plaintext: BufferSource,\n options?: AesGcmEncryptOptions,\n): Promise<AesGcmEncryptResult> {\n if (key.byteLength === 0) {\n throw new Error(\n 'Invalid key length: Key must not be zero bytes for AES-GCM.',\n );\n }\n\n const iv = toUint8Array(options?.unsafeIv ?? getRandomBytes(IV_LENGTH));\n\n if (iv.byteLength === 0) {\n throw new Error(\n 'Invalid IV length: IV must not be zero bytes for AES-GCM.',\n );\n }\n\n if (!options?.unsafeIvLength && iv.byteLength !== IV_LENGTH) {\n throw new Error(\n `Unsafe IV length: IV must be exactly ${IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \\`unsafeIvLength\\` option to \\`true\\`.`,\n );\n }\n\n const subtleKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n key,\n { name: 'AES-GCM' },\n false,\n ['encrypt'],\n );\n\n const ciphertext = await globalThis.crypto.subtle.encrypt(\n // Converting to Uint8Array to work around a Node 22 bug, we may be able to remove in the future.\n {\n name: 'AES-GCM',\n iv,\n additionalData:\n options?.additionalData && toUint8Array(options.additionalData),\n },\n subtleKey,\n toUint8Array(plaintext),\n );\n\n return { ciphertext: new Uint8Array(ciphertext), iv };\n}\n\n/**\n * Decrypt data using AES-GCM.\n *\n * @param key - The 16, 24, or 32-byte AES key.\n * @param iv - The initialization vector.\n * @param ciphertext - The ciphertext.\n * @param options - Additional configuration options.\n * @returns The decrypted plaintext.\n */\nexport async function decrypt(\n key: BufferSource,\n iv: BufferSource,\n ciphertext: BufferSource,\n options?: AesGcmDecryptOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n if (key.byteLength === 0) {\n throw new Error(\n 'Invalid key length: Key must not be zero bytes for AES-GCM.',\n );\n }\n\n if (iv.byteLength === 0) {\n throw new Error(\n 'Invalid IV length: IV must not be zero bytes for AES-GCM.',\n );\n }\n\n if (!options?.unsafeIvLength && iv.byteLength !== IV_LENGTH) {\n throw new Error(\n `Unsafe IV length: IV must be exactly ${IV_LENGTH} bytes for AES-GCM. To bypass this check, set the \\`unsafeIvLength\\` option to \\`true\\`.`,\n );\n }\n\n const subtleKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n key,\n { name: 'AES-GCM' },\n false,\n ['decrypt'],\n );\n\n const plaintext = await globalThis.crypto.subtle.decrypt(\n // Converting to Uint8Array to work around a Node 22 bug, we may be able to remove in the future.\n {\n name: 'AES-GCM',\n iv: toUint8Array(iv),\n additionalData:\n options?.additionalData && toUint8Array(options.additionalData),\n },\n subtleKey,\n toUint8Array(ciphertext),\n );\n\n return new Uint8Array(plaintext);\n}\n"]}
package/dist/hkdf.js CHANGED
@@ -50,8 +50,8 @@ export async function hkdfSha512(ikm, salt, info, keyLength, options) {
50
50
  * @returns The derived key material.
51
51
  */
52
52
  async function hkdf(ikm, hash, salt, info, keyLength, options = {}) {
53
- if (ikm.byteLength === 0) {
54
- throw new Error(`Unsafe input keying material length: IKM must not be zero bytes for HKDF-${hash}.`);
53
+ if (ikm.byteLength === 0 && !options.unsafeInputKeyingMaterial) {
54
+ throw new Error(`Unsafe input keying material length: IKM must not be zero bytes for HKDF-${hash}. To bypass this check, set the \`unsafeInputKeyingMaterial\` option to \`true\`.`);
55
55
  }
56
56
  if (!options.unsafeInputKeyingMaterial && ikm.byteLength < MIN_IKM_LENGTH) {
57
57
  throw new Error(`Unsafe input keying material length: IKM must be at least ${MIN_IKM_LENGTH} bytes for HKDF-${hash}. To bypass this check, set the \`unsafeInputKeyingMaterial\` option to \`true\`.`);
package/dist/hkdf.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hkdf.js","sourceRoot":"","sources":["../src/hkdf.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAG,EAAE,CAAC;AAU1B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAqB;IAErB,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAqB;IAErB,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAqB;IAErB,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,IAAI,CACjB,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAO,GAAgB,EAAE;IAEzB,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,4EAA4E,IAAI,GAAG,CACpF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,yBAAyB,IAAI,GAAG,CAAC,UAAU,GAAG,cAAc,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CACb,6DAA6D,cAAc,mBAAmB,IAAI,mFAAmF,CACtL,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACxD,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,MAAM,EAAE,EAChB,KAAK,EACL,CAAC,YAAY,CAAC,CACf,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAC3D;QACE,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,IAAI;QACJ,IAAI;KACL,EACD,SAAS,EACT,SAAS,GAAG,CAAC,CACd,CAAC;IAEF,OAAO,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;AACrC,CAAC","sourcesContent":["import type { HashFunction } from './types.js';\n\nconst MIN_IKM_LENGTH = 32;\n\nexport type HkdfOptions = {\n /**\n * Skip the minimum IKM length check. Using IKM shorter than 32 bytes\n * reduces the entropy of the derived key material.\n */\n unsafeInputKeyingMaterial?: boolean;\n};\n\n/**\n * Derive key material using HKDF-SHA-256.\n *\n * @param ikm - The input keying material.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nexport async function hkdfSha256(\n ikm: BufferSource,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options?: HkdfOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n return hkdf(ikm, 'SHA-256', salt, info, keyLength, options);\n}\n\n/**\n * Derive key material using HKDF-SHA-384.\n *\n * @param ikm - The input keying material.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nexport async function hkdfSha384(\n ikm: BufferSource,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options?: HkdfOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n return hkdf(ikm, 'SHA-384', salt, info, keyLength, options);\n}\n\n/**\n * Derive key material using HKDF-SHA-512.\n *\n * @param ikm - The input keying material.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nexport async function hkdfSha512(\n ikm: BufferSource,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options?: HkdfOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n return hkdf(ikm, 'SHA-512', salt, info, keyLength, options);\n}\n\n/**\n * Derive key material using HKDF.\n *\n * @param ikm - The input keying material.\n * @param hash - The hash function to use.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nasync function hkdf(\n ikm: BufferSource,\n hash: HashFunction,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options: HkdfOptions = {},\n): Promise<Uint8Array<ArrayBuffer>> {\n if (ikm.byteLength === 0) {\n throw new Error(\n `Unsafe input keying material length: IKM must not be zero bytes for HKDF-${hash}.`,\n );\n }\n\n if (!options.unsafeInputKeyingMaterial && ikm.byteLength < MIN_IKM_LENGTH) {\n throw new Error(\n `Unsafe input keying material length: IKM must be at least ${MIN_IKM_LENGTH} bytes for HKDF-${hash}. To bypass this check, set the \\`unsafeInputKeyingMaterial\\` option to \\`true\\`.`,\n );\n }\n\n const subtleKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n ikm,\n { name: 'HKDF' },\n false,\n ['deriveBits'],\n );\n\n const derivedBits = await globalThis.crypto.subtle.deriveBits(\n {\n name: 'HKDF',\n hash,\n salt,\n info,\n },\n subtleKey,\n keyLength * 8,\n );\n\n return new Uint8Array(derivedBits);\n}\n"]}
1
+ {"version":3,"file":"hkdf.js","sourceRoot":"","sources":["../src/hkdf.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAG,EAAE,CAAC;AAU1B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAqB;IAErB,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAqB;IAErB,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAqB;IAErB,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,IAAI,CACjB,GAAiB,EACjB,IAAkB,EAClB,IAAkB,EAClB,IAAkB,EAClB,SAAiB,EACjB,OAAO,GAAgB,EAAE;IAEzB,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CACb,4EAA4E,IAAI,mFAAmF,CACpK,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,yBAAyB,IAAI,GAAG,CAAC,UAAU,GAAG,cAAc,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CACb,6DAA6D,cAAc,mBAAmB,IAAI,mFAAmF,CACtL,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACxD,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,MAAM,EAAE,EAChB,KAAK,EACL,CAAC,YAAY,CAAC,CACf,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAC3D;QACE,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,IAAI;QACJ,IAAI;KACL,EACD,SAAS,EACT,SAAS,GAAG,CAAC,CACd,CAAC;IAEF,OAAO,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;AACrC,CAAC","sourcesContent":["import type { HashFunction } from './types.js';\n\nconst MIN_IKM_LENGTH = 32;\n\nexport type HkdfOptions = {\n /**\n * Skip the minimum IKM length check. Using IKM shorter than 32 bytes\n * reduces the entropy of the derived key material.\n */\n unsafeInputKeyingMaterial?: boolean;\n};\n\n/**\n * Derive key material using HKDF-SHA-256.\n *\n * @param ikm - The input keying material.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nexport async function hkdfSha256(\n ikm: BufferSource,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options?: HkdfOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n return hkdf(ikm, 'SHA-256', salt, info, keyLength, options);\n}\n\n/**\n * Derive key material using HKDF-SHA-384.\n *\n * @param ikm - The input keying material.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nexport async function hkdfSha384(\n ikm: BufferSource,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options?: HkdfOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n return hkdf(ikm, 'SHA-384', salt, info, keyLength, options);\n}\n\n/**\n * Derive key material using HKDF-SHA-512.\n *\n * @param ikm - The input keying material.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nexport async function hkdfSha512(\n ikm: BufferSource,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options?: HkdfOptions,\n): Promise<Uint8Array<ArrayBuffer>> {\n return hkdf(ikm, 'SHA-512', salt, info, keyLength, options);\n}\n\n/**\n * Derive key material using HKDF.\n *\n * @param ikm - The input keying material.\n * @param hash - The hash function to use.\n * @param salt - The salt to use.\n * @param info - Context and application-specific information.\n * @param keyLength - The desired key length in bytes.\n * @param options - Additional configuration options.\n * @returns The derived key material.\n */\nasync function hkdf(\n ikm: BufferSource,\n hash: HashFunction,\n salt: BufferSource,\n info: BufferSource,\n keyLength: number,\n options: HkdfOptions = {},\n): Promise<Uint8Array<ArrayBuffer>> {\n if (ikm.byteLength === 0 && !options.unsafeInputKeyingMaterial) {\n throw new Error(\n `Unsafe input keying material length: IKM must not be zero bytes for HKDF-${hash}. To bypass this check, set the \\`unsafeInputKeyingMaterial\\` option to \\`true\\`.`,\n );\n }\n\n if (!options.unsafeInputKeyingMaterial && ikm.byteLength < MIN_IKM_LENGTH) {\n throw new Error(\n `Unsafe input keying material length: IKM must be at least ${MIN_IKM_LENGTH} bytes for HKDF-${hash}. To bypass this check, set the \\`unsafeInputKeyingMaterial\\` option to \\`true\\`.`,\n );\n }\n\n const subtleKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n ikm,\n { name: 'HKDF' },\n false,\n ['deriveBits'],\n );\n\n const derivedBits = await globalThis.crypto.subtle.deriveBits(\n {\n name: 'HKDF',\n hash,\n salt,\n info,\n },\n subtleKey,\n keyLength * 8,\n );\n\n return new Uint8Array(derivedBits);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/cryptography",
3
- "version": "1.0.0-preview-9e306636a",
3
+ "version": "1.1.0-preview-c2be02bd4",
4
4
  "description": "Provides optimized versions of commonly used cryptography functions for MetaMask clients",
5
5
  "keywords": [
6
6
  "Ethereum",