Skip to content

Commit dd9077e

Browse files
committed
The module should support AES gcm mode.
Closes #25
1 parent 654a175 commit dd9077e

4 files changed

+186
-29
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,20 @@ Synopsis
3838
========
3939

4040
```nginx
41+
set $key "abcdefghijklmnopqrstuvwxyz123456";
42+
set $iv "1234567812345678";
43+
4144
# key must be of 32 bytes long
45+
encrypted_session_key $key;
46+
4247
encrypted_session_key "abcdefghijklmnopqrstuvwxyz123456";
4348
4449
# iv must not be longer than 16 bytes
4550
# default: "deadbeefdeadbeef" (w/o quotes)
46-
encrypted_session_iv "1234567812345678";
51+
encrypted_session_iv $iv;
52+
53+
encrypted_session_iv_in_content; # enable this only if you rotate IV for each encryption
54+
encrypted_session_mode gcm; # cbc is the default mode.
4755
4856
# default: 1d (1 day)
4957
encrypted_session_expires 3600; # in sec

src/ngx_http_encrypted_session_cipher.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,28 @@
2020
static uint64_t ngx_http_encrypted_session_ntohll(uint64_t n);
2121
static uint64_t ngx_http_encrypted_session_htonll(uint64_t n);
2222

23+
const EVP_CIPHER*
24+
ngx_http_encrypted_session_get_cipher(enum ngx_http_encrypted_session_mode mode)
25+
{
26+
if (mode == ngx_http_encrypted_session_mode_cbc)
27+
{
28+
return EVP_aes_256_cbc();
29+
}
30+
else if (mode == ngx_http_encrypted_session_mode_gcm)
31+
{
32+
return EVP_aes_256_gcm();
33+
}
34+
35+
return NULL;
36+
}
2337

2438
ngx_int_t
2539
ngx_http_encrypted_session_aes_mac_encrypt(
2640
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
2741
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
2842
size_t key_len, const u_char *in, size_t in_len, ngx_uint_t expires,
29-
u_char **dst, size_t *dst_len)
43+
enum ngx_http_encrypted_session_mode mode,
44+
u_char **dst, size_t *dst_len, u_char **tag)
3045
{
3146
const EVP_CIPHER *cipher;
3247
u_char *p, *data;
@@ -50,7 +65,10 @@ ngx_http_encrypted_session_aes_mac_encrypt(
5065
}
5166
}
5267

53-
cipher = EVP_aes_256_cbc();
68+
cipher = ngx_http_encrypted_session_get_cipher(mode);
69+
if (!cipher) {
70+
goto evp_error;
71+
}
5472

5573
block_size = EVP_CIPHER_block_size(cipher);
5674

@@ -107,6 +125,15 @@ ngx_http_encrypted_session_aes_mac_encrypt(
107125
p += len;
108126

109127
ret = EVP_EncryptFinal(emcf->session_ctx, p, &len);
128+
if (!ret) {
129+
goto evp_error;
130+
}
131+
132+
if (mode == ngx_http_encrypted_session_mode_gcm) {
133+
*tag = (u_char*)ngx_pcalloc(pool, ngx_http_encrypted_session_aes_tag_size);
134+
ret = EVP_CIPHER_CTX_ctrl(emcf->session_ctx, EVP_CTRL_GCM_GET_TAG,
135+
ngx_http_encrypted_session_aes_tag_size, *tag);
136+
}
110137

111138
emcf->reset_cipher_ctx(emcf->session_ctx);
112139

@@ -139,8 +166,10 @@ ngx_int_t
139166
ngx_http_encrypted_session_aes_mac_decrypt(
140167
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
141168
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
142-
size_t key_len, const u_char *in, size_t in_len, u_char **dst,
143-
size_t *dst_len)
169+
size_t key_len, const u_char *in, size_t in_len,
170+
enum ngx_http_encrypted_session_mode mode,
171+
u_char *tag,
172+
u_char **dst, size_t *dst_len)
144173
{
145174
const EVP_CIPHER *cipher;
146175
int ret;
@@ -171,7 +200,10 @@ ngx_http_encrypted_session_aes_mac_decrypt(
171200
}
172201
}
173202

174-
cipher = EVP_aes_256_cbc();
203+
cipher = ngx_http_encrypted_session_get_cipher(mode);
204+
if (!cipher) {
205+
goto evp_error;
206+
}
175207

176208
ret = EVP_DecryptInit(emcf->session_ctx, cipher, key, iv);
177209
if (!ret) {
@@ -200,6 +232,14 @@ ngx_http_encrypted_session_aes_mac_decrypt(
200232

201233
p += len;
202234

235+
if (mode == ngx_http_encrypted_session_mode_gcm) {
236+
ret = EVP_CIPHER_CTX_ctrl(emcf->session_ctx, EVP_CTRL_GCM_SET_TAG,
237+
ngx_http_encrypted_session_aes_tag_size, tag);
238+
if (!ret) {
239+
goto evp_error;
240+
}
241+
}
242+
203243
ret = EVP_DecryptFinal(emcf->session_ctx, p, &len);
204244

205245
emcf->reset_cipher_ctx(emcf->session_ctx);

src/ngx_http_encrypted_session_cipher.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,30 @@ typedef struct {
1919

2020
enum {
2121
ngx_http_encrypted_session_key_length = 256 / 8,
22-
ngx_http_encrypted_session_iv_length = EVP_MAX_IV_LENGTH
22+
ngx_http_encrypted_session_iv_length = EVP_MAX_IV_LENGTH,
23+
ngx_http_encrypted_session_aes_tag_size = 16
2324
};
2425

26+
enum ngx_http_encrypted_session_mode {
27+
ngx_http_encrypted_session_mode_unknown = 0, // unknown / unset value.
28+
ngx_http_encrypted_session_mode_cbc = 1, // equivalent of setting cbc string in config or nothing at all.
29+
ngx_http_encrypted_session_mode_gcm = 2 // equivalent of explicitly setting gcm in nginx config.
30+
};
2531

2632
ngx_int_t ngx_http_encrypted_session_aes_mac_encrypt(
2733
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
2834
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
2935
size_t key_len, const u_char *in, size_t in_len,
30-
ngx_uint_t expires, u_char **dst, size_t *dst_len);
36+
ngx_uint_t expires, enum ngx_http_encrypted_session_mode mode,
37+
u_char **dst, size_t *dst_len, u_char **tag);
3138

3239
ngx_int_t ngx_http_encrypted_session_aes_mac_decrypt(
3340
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
3441
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
35-
size_t key_len, const u_char *in, size_t in_len, u_char **dst,
36-
size_t *dst_len);
42+
size_t key_len, const u_char *in, size_t in_len,
43+
enum ngx_http_encrypted_session_mode mode,
44+
u_char *tag,
45+
u_char **dst, size_t *dst_len);
3746

3847
unsigned char* ngx_http_encrypted_session_hmac(
3948
ngx_pool_t *pool,

0 commit comments

Comments
 (0)