Mercurial > dropbear
view libtomcrypt/src/modes/ctr/ctr_encrypt.c @ 1672:3a97f14c0235
Add Chacha20-Poly1305, AES128-GCM and AES256-GCM support (#93)
* Add Chacha20-Poly1305 authenticated encryption
* Add general AEAD approach.
* Add [email protected] algo using LibTomCrypt chacha and
poly1305 routines.
Chacha20-Poly1305 is generally faster than AES256 on CPU w/o dedicated
AES instructions, having the same key size.
Compiling in will add ~5,5kB to binary size on x86-64.
function old new delta
chacha_crypt - 1397 +1397
_poly1305_block - 608 +608
poly1305_done - 595 +595
dropbear_chachapoly_crypt - 457 +457
.rodata 26976 27392 +416
poly1305_process - 290 +290
poly1305_init - 221 +221
chacha_setup - 218 +218
encrypt_packet 1068 1270 +202
dropbear_chachapoly_getlength - 147 +147
decrypt_packet 756 897 +141
chacha_ivctr64 - 137 +137
read_packet 543 637 +94
dropbear_chachapoly_start - 94 +94
read_kex_algos 792 880 +88
chacha_keystream - 69 +69
dropbear_mode_chachapoly - 48 +48
sshciphers 280 320 +40
dropbear_mode_none 24 48 +24
dropbear_mode_ctr 24 48 +24
dropbear_mode_cbc 24 48 +24
dropbear_chachapoly_mac - 24 +24
dropbear_chachapoly - 24 +24
gen_new_keys 848 854 +6
------------------------------------------------------------------------------
(add/remove: 14/0 grow/shrink: 10/0 up/down: 5388/0) Total: 5388 bytes
* Add AES128-GCM and AES256-GCM authenticated encryption
* Add general AES-GCM mode.
* Add [email protected] and [email protected] algo using
LibTomCrypt gcm routines.
AES-GCM is combination of AES CTR mode and GHASH, slower than AES-CTR on
CPU w/o dedicated AES/GHASH instructions therefore disabled by default.
Compiling in will add ~6kB to binary size on x86-64.
function old new delta
gcm_process - 1060 +1060
.rodata 26976 27808 +832
gcm_gf_mult - 820 +820
gcm_add_aad - 660 +660
gcm_shift_table - 512 +512
gcm_done - 471 +471
gcm_add_iv - 384 +384
gcm_init - 347 +347
dropbear_gcm_crypt - 309 +309
encrypt_packet 1068 1270 +202
decrypt_packet 756 897 +141
gcm_reset - 118 +118
read_packet 543 637 +94
read_kex_algos 792 880 +88
sshciphers 280 360 +80
gcm_mult_h - 80 +80
dropbear_gcm_start - 62 +62
dropbear_mode_gcm - 48 +48
dropbear_mode_none 24 48 +24
dropbear_mode_ctr 24 48 +24
dropbear_mode_cbc 24 48 +24
dropbear_ghash - 24 +24
dropbear_gcm_getlength - 24 +24
gen_new_keys 848 854 +6
------------------------------------------------------------------------------
(add/remove: 14/0 grow/shrink: 10/0 up/down: 6434/0) Total: 6434 bytes
author | Vladislav Grishenko <themiron@users.noreply.github.com> |
---|---|
date | Mon, 25 May 2020 20:50:25 +0500 |
parents | 6dba84798cd5 |
children | e9dba7abd939 |
line wrap: on
line source
/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. */ #include "tomcrypt.h" /** @file ctr_encrypt.c CTR implementation, encrypt data, Tom St Denis */ #ifdef LTC_CTR_MODE /** CTR encrypt @param pt Plaintext @param ct [out] Ciphertext @param len Length of plaintext (octets) @param ctr CTR state @return CRYPT_OK if successful */ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) { int x, err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ctr != NULL); if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { return err; } pt += (len / ctr->blocklen) * ctr->blocklen; ct += (len / ctr->blocklen) * ctr->blocklen; len %= ctr->blocklen; } while (len) { /* is the pad empty? */ if (ctr->padlen == ctr->blocklen) { /* increment counter */ if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { /* little-endian */ for (x = 0; x < ctr->ctrlen; x++) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; } } } else { /* big-endian */ for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; } } } /* encrypt it */ if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) { return err; } ctr->padlen = 0; } #ifdef LTC_FAST if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x)); } pt += ctr->blocklen; ct += ctr->blocklen; len -= ctr->blocklen; ctr->padlen = ctr->blocklen; continue; } #endif *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; --len; } return CRYPT_OK; } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */