Skip to content

Commit bea3f30

Browse files
committed
move AES_CTR to its own greatly simplified function
* don't use do_crypt() for stream cipher AES_CTR * rename do_crypt to block_crypt to emphasize its specialization
1 parent a583976 commit bea3f30

File tree

2 files changed

+43
-39
lines changed

2 files changed

+43
-39
lines changed

include/my_crypt.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,9 @@ extern "C" {
4141
int my_aes_encrypt_ctr(const uchar* source, uint source_length,
4242
uchar* dest, uint* dest_length,
4343
const uchar* key, uint key_length,
44-
const uchar* iv, uint iv_length,
45-
int no_padding);
44+
const uchar* iv, uint iv_length);
4645

47-
int my_aes_decrypt_ctr(const uchar* source, uint source_length,
48-
uchar* dest, uint* dest_length,
49-
const uchar* key, uint key_length,
50-
const uchar* iv, uint iv_length,
51-
int no_padding);
46+
#define my_aes_decrypt_ctr my_aes_encrypt_ctr
5247

5348
#endif
5449

mysys_ssl/my_crypt.cc

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static const Dir CRYPT_DECRYPT = 0;
4242
typedef const EVP_CIPHER *CipherMode;
4343

4444
#define make_aes_dispatcher(mode) \
45-
static inline CipherMode aes_ ## mode(uint key_length) \
45+
static inline CipherMode aes_ ## mode(uint key_length) \
4646
{ \
4747
switch (key_length) { \
4848
case 16: return EVP_aes_128_ ## mode(); \
@@ -54,9 +54,6 @@ typedef const EVP_CIPHER *CipherMode;
5454

5555
make_aes_dispatcher(ecb)
5656
make_aes_dispatcher(cbc)
57-
#ifdef HAVE_EncryptAes128Ctr
58-
make_aes_dispatcher(ctr)
59-
#endif
6057

6158
typedef uchar KeyByte;
6259

@@ -66,11 +63,11 @@ struct MyCTX : EVP_CIPHER_CTX {
6663
};
6764
#endif
6865

69-
static int do_crypt(CipherMode cipher, Dir dir,
70-
const uchar* source, uint source_length,
71-
uchar* dest, uint* dest_length,
72-
const KeyByte *key, uint key_length,
73-
const KeyByte *iv, uint iv_length, int no_padding)
66+
static int block_crypt(CipherMode cipher, Dir dir,
67+
const uchar* source, uint source_length,
68+
uchar* dest, uint* dest_length,
69+
const KeyByte *key, uint key_length,
70+
const KeyByte *iv, uint iv_length, int no_padding)
7471
{
7572
int tail= source_length % MY_AES_BLOCK_SIZE;
7673

@@ -125,7 +122,7 @@ static int do_crypt(CipherMode cipher, Dir dir,
125122

126123
DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)key_length);
127124
DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(&ctx) == (int)iv_length);
128-
DBUG_ASSERT(EVP_CIPHER_CTX_block_size(&ctx) == MY_AES_BLOCK_SIZE || !no_padding);
125+
DBUG_ASSERT(EVP_CIPHER_CTX_block_size(&ctx) == MY_AES_BLOCK_SIZE);
129126

130127
/* use built-in OpenSSL padding, if possible */
131128
if (!EVP_CipherUpdate(&ctx, dest, (int*)dest_length,
@@ -163,27 +160,39 @@ static int do_crypt(CipherMode cipher, Dir dir,
163160
C_MODE_START
164161

165162
#ifdef HAVE_EncryptAes128Ctr
163+
make_aes_dispatcher(ctr)
166164

165+
/*
166+
special simplified implementation for CTR, because it's a stream cipher
167+
(doesn't need padding, always encrypts the specified number of bytes), and
168+
because encrypting and decrypting code is exactly the same (courtesy of XOR)
169+
*/
167170
int my_aes_encrypt_ctr(const uchar* source, uint source_length,
168171
uchar* dest, uint* dest_length,
169172
const uchar* key, uint key_length,
170-
const uchar* iv, uint iv_length,
171-
int no_padding)
173+
const uchar* iv, uint iv_length)
172174
{
173-
/* CTR is a stream cipher mode, it needs no special padding code */
174-
return do_crypt(aes_ctr(key_length), CRYPT_ENCRYPT, source, source_length,
175-
dest, dest_length, key, key_length, iv, iv_length, 0);
176-
}
175+
CipherMode cipher= aes_ctr(key_length);
176+
struct MyCTX ctx;
177+
int fin __attribute__((unused));
177178

179+
if (unlikely(!cipher))
180+
return MY_AES_BAD_KEYSIZE;
178181

179-
int my_aes_decrypt_ctr(const uchar* source, uint source_length,
180-
uchar* dest, uint* dest_length,
181-
const uchar* key, uint key_length,
182-
const uchar* iv, uint iv_length,
183-
int no_padding)
184-
{
185-
return do_crypt(aes_ctr(key_length), CRYPT_DECRYPT, source, source_length,
186-
dest, dest_length, key, key_length, iv, iv_length, 0);
182+
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, CRYPT_ENCRYPT))
183+
return MY_AES_OPENSSL_ERROR;
184+
185+
DBUG_ASSERT(EVP_CIPHER_CTX_key_length(&ctx) == (int)key_length);
186+
DBUG_ASSERT(EVP_CIPHER_CTX_iv_length(&ctx) == (int)iv_length);
187+
DBUG_ASSERT(EVP_CIPHER_CTX_block_size(&ctx) == 1);
188+
189+
if (!EVP_CipherUpdate(&ctx, dest, (int*)dest_length, source, source_length))
190+
return MY_AES_OPENSSL_ERROR;
191+
192+
DBUG_ASSERT(EVP_CipherFinal_ex(&ctx, dest + *dest_length, &fin));
193+
DBUG_ASSERT(fin == 0);
194+
195+
return MY_AES_OK;
187196
}
188197

189198
#endif /* HAVE_EncryptAes128Ctr */
@@ -194,8 +203,8 @@ int my_aes_encrypt_ecb(const uchar* source, uint source_length,
194203
const uchar* iv, uint iv_length,
195204
int no_padding)
196205
{
197-
return do_crypt(aes_ecb(key_length), CRYPT_ENCRYPT, source, source_length,
198-
dest, dest_length, key, key_length, 0, 0, no_padding);
206+
return block_crypt(aes_ecb(key_length), CRYPT_ENCRYPT, source, source_length,
207+
dest, dest_length, key, key_length, 0, 0, no_padding);
199208
}
200209

201210
int my_aes_decrypt_ecb(const uchar* source, uint source_length,
@@ -204,8 +213,8 @@ int my_aes_decrypt_ecb(const uchar* source, uint source_length,
204213
const uchar* iv, uint iv_length,
205214
int no_padding)
206215
{
207-
return do_crypt(aes_ecb(key_length), CRYPT_DECRYPT, source, source_length,
208-
dest, dest_length, key, key_length, 0, 0, no_padding);
216+
return block_crypt(aes_ecb(key_length), CRYPT_DECRYPT, source, source_length,
217+
dest, dest_length, key, key_length, 0, 0, no_padding);
209218
}
210219

211220
int my_aes_encrypt_cbc(const uchar* source, uint source_length,
@@ -214,8 +223,8 @@ int my_aes_encrypt_cbc(const uchar* source, uint source_length,
214223
const uchar* iv, uint iv_length,
215224
int no_padding)
216225
{
217-
return do_crypt(aes_cbc(key_length), CRYPT_ENCRYPT, source, source_length,
218-
dest, dest_length, key, key_length, iv, iv_length, no_padding);
226+
return block_crypt(aes_cbc(key_length), CRYPT_ENCRYPT, source, source_length,
227+
dest, dest_length, key, key_length, iv, iv_length, no_padding);
219228
}
220229

221230
int my_aes_decrypt_cbc(const uchar* source, uint source_length,
@@ -224,8 +233,8 @@ int my_aes_decrypt_cbc(const uchar* source, uint source_length,
224233
const uchar* iv, uint iv_length,
225234
int no_padding)
226235
{
227-
return do_crypt(aes_cbc(key_length), CRYPT_DECRYPT, source, source_length,
228-
dest, dest_length, key, key_length, iv, iv_length, no_padding);
236+
return block_crypt(aes_cbc(key_length), CRYPT_DECRYPT, source, source_length,
237+
dest, dest_length, key, key_length, iv, iv_length, no_padding);
229238
}
230239

231240
C_MODE_END

0 commit comments

Comments
 (0)