Skip to content

Commit b85978c

Browse files
authored
feat(encryption): add AES-SIV support and legacy blind-index errors (#5044)
1 parent 1add2d0 commit b85978c

8 files changed

Lines changed: 133 additions & 3 deletions

File tree

modules/encryption/define_config.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { configProvider } from '../../src/config_provider.ts'
1212
import { type ConfigProvider } from '../../src/types.ts'
1313

1414
import {
15+
type AESSIVDriverConfig,
1516
type AES256CBCDriverConfig,
1617
type AES256GCMDriverConfig,
1718
type ChaCha20Poly1305DriverConfig,
@@ -198,6 +199,21 @@ export const drivers: {
198199
*/
199200
aes256gcm: (config: AES256GCMDriverConfig) => ConfigProvider<EncryptionConfig>
200201

202+
/**
203+
* Creates an AES-SIV encryption driver configuration.
204+
*
205+
* @param config - The AES-SIV driver configuration
206+
*
207+
* @example
208+
* ```ts
209+
* drivers.aessiv({
210+
* id: 'app',
211+
* key: env.get('APP_KEY')
212+
* })
213+
* ```
214+
*/
215+
aessiv: (config: AESSIVDriverConfig) => ConfigProvider<EncryptionConfig>
216+
201217
/**
202218
* Creates a Legacy encryption driver configuration.
203219
*
@@ -251,6 +267,17 @@ export const drivers: {
251267
})
252268
},
253269

270+
aessiv: (config) => {
271+
return configProvider.create(async () => {
272+
const { AESSIV } = await import('./drivers/aes_siv.ts')
273+
debug('configuring aessiv encryption driver')
274+
return {
275+
driver: (key) => new AESSIV({ id: config.id, key }),
276+
keys: [config.key].filter((key) => !!key),
277+
}
278+
})
279+
},
280+
254281
legacy: (config) => {
255282
return configProvider.create(async () => {
256283
const { Legacy } = await import('./drivers/legacy.ts')
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* @adonisjs/core
3+
*
4+
* (c) AdonisJS
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
/**
11+
* AES-SIV encryption driver implementation.
12+
*
13+
* This driver provides deterministic authenticated encryption using AES-SIV
14+
* (Synthetic Initialization Vector). It is useful when you need equality
15+
* queries over encrypted values while preserving authenticity guarantees.
16+
*
17+
* @example
18+
* ```ts
19+
* const driver = new AESSIV({
20+
* id: 'app',
21+
* key: 'your-256-bit-key-here'
22+
* })
23+
*
24+
* const encrypted = driver.encrypt('sensitive data')
25+
* const decrypted = driver.decrypt(encrypted)
26+
* ```
27+
*/
28+
export { AESSIV } from '@boringnode/encryption/drivers/aes_siv'

modules/encryption/drivers/legacy.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
EncryptOptions,
1717
} from '@boringnode/encryption/types'
1818
import { errors } from '@boringnode/encryption'
19+
import { E_LEGACY_BLIND_INDEX_NOT_SUPPORTED } from '../errors.ts'
1920

2021
/**
2122
* Configuration for the Legacy encryption driver.
@@ -183,4 +184,18 @@ export class Legacy extends BaseDriver implements EncryptionDriverContract {
183184
return null
184185
}
185186
}
187+
188+
/**
189+
* Legacy driver does not support blind indexes.
190+
*/
191+
blindIndex(_payload: any, _purpose: string): string {
192+
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
193+
}
194+
195+
/**
196+
* Legacy driver does not support blind indexes.
197+
*/
198+
blindIndexes(_payload: any, _purpose: string): string[] {
199+
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
200+
}
186201
}

modules/encryption/errors.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* @adonisjs/core
3+
*
4+
* (c) AdonisJS
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { createError } from '../../src/exceptions.ts'
11+
import { errors as boringnodeErrors } from '@boringnode/encryption'
12+
13+
/**
14+
* Raised when attempting to compute blind indexes using the legacy driver.
15+
*/
16+
export const E_LEGACY_BLIND_INDEX_NOT_SUPPORTED = createError(
17+
'Blind indexes are not supported by the legacy encryption driver',
18+
'E_LEGACY_BLIND_INDEX_NOT_SUPPORTED'
19+
)
20+
21+
/**
22+
* Encryption errors exposed by this package.
23+
*/
24+
export const errors = {
25+
...boringnodeErrors,
26+
E_LEGACY_BLIND_INDEX_NOT_SUPPORTED,
27+
}

modules/encryption/main.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ export { Hmac } from '@boringnode/encryption'
8181
*/
8282
export { BaseDriver } from '@boringnode/encryption'
8383

84+
/**
85+
* Encryption module specific exceptions.
86+
*/
87+
export { errors } from './errors.ts'
88+
8489
/**
8590
* Defines the encryption configuration for the application.
8691
*
@@ -91,8 +96,8 @@ export { defineConfig } from './define_config.ts'
9196
/**
9297
* Collection of built-in encryption driver factory functions.
9398
*
94-
* Includes factories for ChaCha20-Poly1305, AES-256-CBC, and
95-
* AES-256-GCM encryption algorithms.
99+
* Includes factories for ChaCha20-Poly1305, AES-256-CBC,
100+
* AES-256-GCM, and AES-SIV encryption algorithms.
96101
*
97102
* @see {drivers} in define_config.ts for detailed documentation
98103
*/

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"./encryption": "./build/modules/encryption/main.js",
4343
"./encryption/drivers/aes_256_cbc": "./build/modules/encryption/drivers/aes_256_cbc.js",
4444
"./encryption/drivers/aes_256_gcm": "./build/modules/encryption/drivers/aes_256_gcm.js",
45+
"./encryption/drivers/aes_siv": "./build/modules/encryption/drivers/aes_siv.js",
4546
"./encryption/drivers/chacha20_poly1305": "./build/modules/encryption/drivers/chacha20_poly1305.js",
4647
"./env": "./build/modules/env/main.js",
4748
"./dumper": "./build/modules/dumper/main.js",
@@ -129,7 +130,7 @@
129130
"@adonisjs/fold": "^11.0.0-next.4",
130131
"@adonisjs/hash": "^10.0.0-next.2",
131132
"@adonisjs/health": "^3.1.0-next.1",
132-
"@adonisjs/http-server": "^8.0.0-next.18",
133+
"@adonisjs/http-server": "^8.0.0-next.19",
133134
"@adonisjs/http-transformers": "^2.2.0",
134135
"@adonisjs/logger": "^7.1.0-next.3",
135136
"@adonisjs/repl": "^5.0.0-next.2",

tests/encryption/legacy.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,23 @@ test.group('Legacy | defineConfig', () => {
272272
assert.deepEqual(config.list.legacy.keys, [SECRET_KEY])
273273
})
274274
})
275+
276+
test.group('Legacy | blind indexes', () => {
277+
test('throw when computing blind index', ({ assert }) => {
278+
const encryption = new Legacy({ key: SECRET_KEY })
279+
280+
assert.throws(
281+
() => encryption.blindIndex('foo@example.com', 'users.email'),
282+
'Blind indexes are not supported by the legacy encryption driver'
283+
)
284+
})
285+
286+
test('throw when computing blind indexes', ({ assert }) => {
287+
const encryption = new Legacy({ key: SECRET_KEY })
288+
289+
assert.throws(
290+
() => encryption.blindIndexes('foo@example.com', 'users.email'),
291+
'Blind indexes are not supported by the legacy encryption driver'
292+
)
293+
})
294+
})

types/encryption.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ export type { AES256CBCDriverConfig } from '@boringnode/encryption/drivers/aes_2
4242
*/
4343
export type { AES256GCMDriverConfig } from '@boringnode/encryption/drivers/aes_256_gcm'
4444

45+
/**
46+
* Configuration options for the AES-SIV encryption driver.
47+
*
48+
* Includes the driver identifier and a single encryption key.
49+
*/
50+
export type { AESSIVDriverConfig } from '@boringnode/encryption/drivers/aes_siv'
51+
4552
/**
4653
* Configuration options for the ChaCha20-Poly1305 encryption driver.
4754
*

0 commit comments

Comments
 (0)