crypt: use EVP_CIPHER_CTX_new() instead of _init()
[siplcs.git] / src / core / sipe-crypt-openssl.c
blob047e8762a8e9b49fea4e18b9dca9e8cf6aa47a22
1 /**
2 * @file sipe-crypt-openssl.c
4 * pidgin-sipe
6 * Copyright (C) 2013-2017 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /**
24 * Cipher routines implementation based on OpenSSL.
26 #include <openssl/evp.h>
27 #include <openssl/rsa.h>
29 #include "glib.h"
31 #include "sipe-common.h"
32 #include "sipe-backend.h"
33 #include "sipe-crypt.h"
35 /* OpenSSL specific initialization/shutdown */
36 void sipe_crypto_init(SIPE_UNUSED_PARAMETER gboolean production_mode)
38 /* nothing to do here */
41 void sipe_crypto_shutdown(void)
43 /* nothing to do here */
46 static void openssl_oneshot_crypt(const EVP_CIPHER *type,
47 const guchar *key, gsize key_length,
48 const guchar *plaintext, gsize plaintext_length,
49 guchar *encrypted_text)
51 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
52 int encrypted_length = 0;
54 /* initialize context */
55 EVP_EncryptInit_ex(ctx, type, NULL, key, NULL);
57 /* set encryption parameters */
58 if (key_length)
59 EVP_CIPHER_CTX_set_key_length(ctx, key_length);
60 EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL);
62 /* encrypt */
63 EVP_EncryptUpdate(ctx,
64 encrypted_text, &encrypted_length,
65 plaintext, plaintext_length);
66 encrypted_text += encrypted_length;
67 EVP_EncryptFinal_ex(ctx, encrypted_text, &encrypted_length);
69 /* cleanup */
70 EVP_CIPHER_CTX_free(ctx);
73 /* DES CBC with 56-bit key */
74 void sipe_crypt_des(const guchar *key,
75 const guchar *plaintext, gsize plaintext_length,
76 guchar *encrypted_text)
78 openssl_oneshot_crypt(EVP_des_cbc(),
79 key, 0 /* fixed length */,
80 plaintext, plaintext_length,
81 encrypted_text);
84 /* RC4 with variable length key */
85 void sipe_crypt_rc4(const guchar *key, gsize key_length,
86 const guchar *plaintext, gsize plaintext_length,
87 guchar *encrypted_text)
89 openssl_oneshot_crypt(EVP_rc4(),
90 key, key_length,
91 plaintext, plaintext_length,
92 encrypted_text);
95 gboolean sipe_crypt_rsa_encrypt(gpointer public,
96 gsize modulus_length,
97 const guchar *plaintext,
98 guchar *encrypted_text)
100 return(RSA_public_encrypt(modulus_length,
101 plaintext,
102 encrypted_text,
103 public,
104 RSA_NO_PADDING)
105 != -1);
108 gboolean sipe_crypt_rsa_decrypt(gpointer private,
109 gsize modulus_length,
110 const guchar *encrypted_text,
111 guchar *plaintext)
113 return(RSA_private_decrypt(modulus_length,
114 encrypted_text,
115 plaintext,
116 private,
117 RSA_NO_PADDING)
118 != -1);
121 guchar *sipe_crypt_rsa_sign(gpointer private,
122 const guchar *digest, gsize digest_length,
123 gsize *signature_length)
125 guchar *signature = g_malloc(RSA_size(private));
126 unsigned int length;
128 if (!RSA_sign(NID_md5_sha1,
129 digest, digest_length,
130 signature, &length,
131 private)) {
132 g_free(signature);
133 return(NULL);
136 *signature_length = length;
137 return(signature);
140 gboolean sipe_crypt_verify_rsa(gpointer public,
141 const guchar *digest, gsize digest_length,
142 const guchar *signature, gsize signature_length)
144 return(RSA_verify(NID_md5_sha1,
145 digest, digest_length,
146 /* older OpenSSL version don't have "const" here */
147 (guchar *) signature, signature_length,
148 public));
151 static gpointer openssl_EVP_init(const EVP_CIPHER *type,
152 const guchar *key,
153 gsize key_length,
154 const guchar *iv)
156 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
158 /* initialize context */
159 EVP_EncryptInit_ex(ctx, type, NULL, key, iv);
161 /* set encryption parameters */
162 EVP_CIPHER_CTX_set_key_length(ctx, key_length);
163 EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv);
165 return(ctx);
168 /* Stream RC4 cipher for file transfer with fixed-length 128-bit key */
169 gpointer sipe_crypt_ft_start(const guchar *key)
171 return(openssl_EVP_init(EVP_rc4(), key, 16, NULL));
174 void sipe_crypt_ft_stream(gpointer context,
175 const guchar *in, gsize length,
176 guchar *out)
178 int tmp;
179 EVP_EncryptUpdate(context, out, &tmp, in, length);
182 void sipe_crypt_ft_destroy(gpointer context)
184 EVP_CIPHER_CTX_free(context);
187 /* Stream RC4 cipher for TLS with variable key length */
188 gpointer sipe_crypt_tls_start(const guchar *key, gsize key_length)
190 return(openssl_EVP_init(EVP_rc4(), key, key_length, NULL));
193 void sipe_crypt_tls_stream(gpointer context,
194 const guchar *in, gsize length,
195 guchar *out)
197 int tmp;
198 EVP_EncryptUpdate(context, out, &tmp, in, length);
201 void sipe_crypt_tls_destroy(gpointer context)
203 EVP_CIPHER_CTX_free(context);
206 /* Block AES-CBC cipher for TLS */
207 void sipe_crypt_tls_block(const guchar *key, gsize key_length,
208 const guchar *iv,
209 /* OpenSSL assumes that iv is of correct size */
210 SIPE_UNUSED_PARAMETER gsize iv_length,
211 const guchar *in, gsize length,
212 guchar *out)
214 const EVP_CIPHER *type = NULL;
216 switch (key_length) {
217 case 128 / 8:
218 type = EVP_aes_128_cbc();
219 break;
221 * TLS does not use AES-192
223 case 192 / 8:
224 type = EVP_aes_192_cbc();
225 break;
227 case 256 / 8:
228 type = EVP_aes_256_cbc();
229 break;
230 default:
231 SIPE_DEBUG_ERROR("sipe_crypt_tls_block: unsupported key length %" G_GSIZE_FORMAT " bytes for AES CBC",
232 key_length);
233 break;
236 if (type) {
237 EVP_CIPHER_CTX *context = openssl_EVP_init(type,
238 key, key_length,
239 iv);
241 if (context) {
242 int tmp;
243 EVP_EncryptUpdate(context, out, &tmp, in, length);
244 EVP_CIPHER_CTX_free(context);
250 Local Variables:
251 mode: c
252 c-file-style: "bsd"
253 indent-tabs-mode: t
254 tab-width: 8
255 End: