Mercurial > dropbear
view libtomcrypt/src/mac/pmac/pmac_init.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 |
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 pmac_init.c PMAC implementation, initialize state, by Tom St Denis */ #ifdef LTC_PMAC static const struct { int len; unsigned char poly_div[MAXBLOCKSIZE], poly_mul[MAXBLOCKSIZE]; } polys[] = { { 8, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } }, { 16, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } } }; /** Initialize a PMAC state @param pmac The PMAC state to initialize @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @return CRYPT_OK if successful */ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen) { int poly, x, y, m, err; unsigned char *L; LTC_ARGCHK(pmac != NULL); LTC_ARGCHK(key != NULL); /* valid cipher? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* determine which polys to use */ pmac->block_len = cipher_descriptor[cipher].block_length; for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { if (polys[poly].len == pmac->block_len) { break; } } if (poly >= (int)(sizeof(polys)/sizeof(polys[0]))) { return CRYPT_INVALID_ARG; } if (polys[poly].len != pmac->block_len) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (pmac->block_len % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* schedule the key */ if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) { return err; } /* allocate L */ L = XMALLOC(pmac->block_len); if (L == NULL) { return CRYPT_MEM; } /* find L = E[0] */ zeromem(L, pmac->block_len); if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) { goto error; } /* find Ls[i] = L << i for i == 0..31 */ XMEMCPY(pmac->Ls[0], L, pmac->block_len); for (x = 1; x < 32; x++) { m = pmac->Ls[x-1][0] >> 7; for (y = 0; y < pmac->block_len-1; y++) { pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255; } pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255; if (m == 1) { for (y = 0; y < pmac->block_len; y++) { pmac->Ls[x][y] ^= polys[poly].poly_mul[y]; } } } /* find Lr = L / x */ m = L[pmac->block_len-1] & 1; /* shift right */ for (x = pmac->block_len - 1; x > 0; x--) { pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255; } pmac->Lr[0] = L[0] >> 1; if (m == 1) { for (x = 0; x < pmac->block_len; x++) { pmac->Lr[x] ^= polys[poly].poly_div[x]; } } /* zero buffer, counters, etc... */ pmac->block_index = 1; pmac->cipher_idx = cipher; pmac->buflen = 0; zeromem(pmac->block, sizeof(pmac->block)); zeromem(pmac->Li, sizeof(pmac->Li)); zeromem(pmac->checksum, sizeof(pmac->checksum)); err = CRYPT_OK; error: #ifdef LTC_CLEAN_STACK zeromem(L, pmac->block_len); #endif XFREE(L); return err; } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */