openssl: patch to fix devcrypto sessions leak
[openwrt/staging/wigyori.git] / package / libs / openssl / patches / 300-eng_devcrypto-close-open-session-on-init.patch
1 From 82b269fd77d20aa86d0825d798f3045dfe0a7a86 Mon Sep 17 00:00:00 2001
2 From: Eneas U de Queiroz <cote2004-github@yahoo.com>
3 Date: Tue, 12 Feb 2019 10:44:19 -0200
4 Subject: [PATCH] eng_devcrypto: close open session on init
5
6 cipher_init may be called on an already initialized context, without a
7 necessary cleanup. This separates cleanup from initialization, closing
8 an eventual open session before creating a new one.
9
10 Move the /dev/crypto session cleanup code to its own function.
11
12 Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
13
14 --- a/crypto/engine/eng_devcrypto.c
15 +++ b/crypto/engine/eng_devcrypto.c
16 @@ -35,6 +35,15 @@
17 */
18 static int cfd;
19
20 +static int clean_devcrypto_session(struct session_op *sess) {
21 + if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
22 + SYSerr(SYS_F_IOCTL, errno);
23 + return 0;
24 + }
25 + memset(sess, 0, sizeof(struct session_op));
26 + return 1;
27 +}
28 +
29 /******************************************************************************
30 *
31 * Ciphers
32 @@ -143,7 +152,11 @@ static int cipher_init(EVP_CIPHER_CTX *c
33 const struct cipher_data_st *cipher_d =
34 get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
35
36 - memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
37 + /* cleanup a previous session */
38 + if (cipher_ctx->sess.ses != 0 &&
39 + clean_devcrypto_session(&cipher_ctx->sess) == 0)
40 + return 0;
41 +
42 cipher_ctx->sess.cipher = cipher_d->devcryptoid;
43 cipher_ctx->sess.keylen = cipher_d->keylen;
44 cipher_ctx->sess.key = (void *)key;
45 @@ -282,15 +295,29 @@ static int ctr_do_cipher(EVP_CIPHER_CTX
46
47 static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
48 {
49 + struct cipher_ctx *cipher_ctx =
50 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
51 EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
52 - struct cipher_ctx *cipher_ctx;
53 + struct cipher_ctx *to_cipher_ctx;
54 +
55 + switch (type) {
56
57 - if (type == EVP_CTRL_COPY) {
58 + case EVP_CTRL_COPY:
59 + if (cipher_ctx == NULL)
60 + return 1;
61 /* when copying the context, a new session needs to be initialized */
62 - cipher_ctx = (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
63 - return (cipher_ctx == NULL)
64 - || cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
65 + to_cipher_ctx =
66 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx);
67 + memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess));
68 + return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
69 (cipher_ctx->op == COP_ENCRYPT));
70 +
71 + case EVP_CTRL_INIT:
72 + memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
73 + return 1;
74 +
75 + default:
76 + break;
77 }
78
79 return -1;
80 @@ -301,12 +328,7 @@ static int cipher_cleanup(EVP_CIPHER_CTX
81 struct cipher_ctx *cipher_ctx =
82 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
83
84 - if (ioctl(cfd, CIOCFSESSION, &cipher_ctx->sess.ses) < 0) {
85 - SYSerr(SYS_F_IOCTL, errno);
86 - return 0;
87 - }
88 -
89 - return 1;
90 + return clean_devcrypto_session(&cipher_ctx->sess);
91 }
92
93 /*
94 @@ -352,6 +374,7 @@ static void prepare_cipher_methods(void)
95 || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
96 cipher_data[i].flags
97 | EVP_CIPH_CUSTOM_COPY
98 + | EVP_CIPH_CTRL_INIT
99 | EVP_CIPH_FLAG_DEFAULT_ASN1)
100 || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
101 || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
102 @@ -594,11 +617,8 @@ static int digest_cleanup(EVP_MD_CTX *ct
103
104 if (digest_ctx == NULL)
105 return 1;
106 - if (ioctl(cfd, CIOCFSESSION, &digest_ctx->sess.ses) < 0) {
107 - SYSerr(SYS_F_IOCTL, errno);
108 - return 0;
109 - }
110 - return 1;
111 +
112 + return clean_devcrypto_session(&digest_ctx->sess);
113 }
114
115 static int devcrypto_test_digest(size_t digest_data_index)