diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-11-23 18:31:26 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-11-23 18:31:26 +0100 |
| commit | ecc9090cfcccf412288147f385808f8f9df97ebe (patch) | |
| tree | 0c937204026d3a2420597180e3db07cb3896ade3 | |
| parent | 5e4236d226309a32842a6928878fd0e1cd5937e7 (diff) | |
| download | busybox-w32-ecc9090cfcccf412288147f385808f8f9df97ebe.tar.gz busybox-w32-ecc9090cfcccf412288147f385808f8f9df97ebe.tar.bz2 busybox-w32-ecc9090cfcccf412288147f385808f8f9df97ebe.zip | |
tls: simplify aesgcm_GHASH()
function old new delta
xwrite_encrypted 604 599 -5
FlattenSzInBits 52 - -52
aesgcm_GHASH 395 262 -133
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 0/2 up/down: 0/-190) Total: -190 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | networking/tls.c | 30 | ||||
| -rw-r--r-- | networking/tls_aesgcm.c | 73 | ||||
| -rw-r--r-- | networking/tls_aesgcm.h | 4 |
3 files changed, 60 insertions, 47 deletions
diff --git a/networking/tls.c b/networking/tls.c index 23622d76e..3b4f1b7e2 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
| @@ -270,7 +270,7 @@ struct record_hdr { | |||
| 270 | enum { | 270 | enum { |
| 271 | NEED_EC_KEY = 1 << 0, | 271 | NEED_EC_KEY = 1 << 0, |
| 272 | GOT_CERT_RSA_KEY_ALG = 1 << 1, | 272 | GOT_CERT_RSA_KEY_ALG = 1 << 1, |
| 273 | GOT_CERT_ECDSA_KEY_ALG = 1 << 2, | 273 | GOT_CERT_ECDSA_KEY_ALG = 1 << 2, |
| 274 | GOT_EC_KEY = 1 << 3, | 274 | GOT_EC_KEY = 1 << 3, |
| 275 | ENCRYPTION_AESGCM = 1 << 4, | 275 | ENCRYPTION_AESGCM = 1 << 4, |
| 276 | }; | 276 | }; |
| @@ -756,7 +756,6 @@ static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, un | |||
| 756 | } while ((size & (AES_BLOCK_SIZE - 1)) != 0); | 756 | } while ((size & (AES_BLOCK_SIZE - 1)) != 0); |
| 757 | 757 | ||
| 758 | /* Encrypt content+MAC+padding in place */ | 758 | /* Encrypt content+MAC+padding in place */ |
| 759 | //optimize key setup | ||
| 760 | aes_cbc_encrypt( | 759 | aes_cbc_encrypt( |
| 761 | &tls->aes_decrypt, /* selects 128/256 */ | 760 | &tls->aes_decrypt, /* selects 128/256 */ |
| 762 | buf - AES_BLOCK_SIZE, /* IV */ | 761 | buf - AES_BLOCK_SIZE, /* IV */ |
| @@ -787,8 +786,9 @@ static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, un | |||
| 787 | */ | 786 | */ |
| 788 | static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned type) | 787 | static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned type) |
| 789 | { | 788 | { |
| 790 | //go for [16] | 789 | #define COUNTER(v) (*(uint32_t*)(v + 12)) |
| 791 | uint8_t aad[13]; | 790 | |
| 791 | uint8_t aad[13 + 3]; /* +3 creates [16] buffer, simplifying GHASH() */ | ||
| 792 | uint8_t nonce[12 + 4]; /* +4 creates space for AES block counter */ | 792 | uint8_t nonce[12 + 4]; /* +4 creates space for AES block counter */ |
| 793 | uint8_t scratch[AES_BLOCK_SIZE]; //[16] | 793 | uint8_t scratch[AES_BLOCK_SIZE]; //[16] |
| 794 | uint8_t authtag[AES_BLOCK_SIZE]; //[16] | 794 | uint8_t authtag[AES_BLOCK_SIZE]; //[16] |
| @@ -807,7 +807,8 @@ static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned ty | |||
| 807 | aad[9] = TLS_MAJ; | 807 | aad[9] = TLS_MAJ; |
| 808 | aad[10] = TLS_MIN; | 808 | aad[10] = TLS_MIN; |
| 809 | aad[11] = size >> 8; | 809 | aad[11] = size >> 8; |
| 810 | aad[12] = size & 0xff; | 810 | /* set aad[12], and clear aad[13..15] */ |
| 811 | COUNTER(aad) = SWAP_LE32(size & 0xff); | ||
| 811 | 812 | ||
| 812 | memcpy(nonce, tls->client_write_IV, 4); | 813 | memcpy(nonce, tls->client_write_IV, 4); |
| 813 | memcpy(nonce + 4, &tls->write_seq64_be, 8); | 814 | memcpy(nonce + 4, &tls->write_seq64_be, 8); |
| @@ -817,8 +818,6 @@ static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned ty | |||
| 817 | /* seq64 is not used later in this func, can increment here */ | 818 | /* seq64 is not used later in this func, can increment here */ |
| 818 | tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be)); | 819 | tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be)); |
| 819 | 820 | ||
| 820 | #define COUNTER(v) (*(uint32_t*)(v + 12)) | ||
| 821 | |||
| 822 | cnt = 1; | 821 | cnt = 1; |
| 823 | remaining = size; | 822 | remaining = size; |
| 824 | while (remaining != 0) { | 823 | while (remaining != 0) { |
| @@ -833,8 +832,7 @@ static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned ty | |||
| 833 | remaining -= n; | 832 | remaining -= n; |
| 834 | } | 833 | } |
| 835 | 834 | ||
| 836 | //optimize fixed sizes | 835 | aesgcm_GHASH(tls->H, aad, /*sizeof(aad),*/ tls->outbuf + OUTBUF_PFX, size, authtag /*, sizeof(authtag)*/); |
| 837 | aesgcm_GHASH(tls->H, aad, sizeof(aad), tls->outbuf + OUTBUF_PFX, size, authtag, sizeof(authtag)); | ||
| 838 | COUNTER(nonce) = htonl(1); | 836 | COUNTER(nonce) = htonl(1); |
| 839 | aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); | 837 | aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); |
| 840 | xorbuf(authtag, scratch, sizeof(authtag)); | 838 | xorbuf(authtag, scratch, sizeof(authtag)); |
| @@ -923,8 +921,9 @@ static const char *alert_text(int code) | |||
| 923 | 921 | ||
| 924 | static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size) | 922 | static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size) |
| 925 | { | 923 | { |
| 926 | //go for [16] | 924 | #define COUNTER(v) (*(uint32_t*)(v + 12)) |
| 927 | //uint8_t aad[13]; | 925 | |
| 926 | //uint8_t aad[13 + 3]; /* +3 creates [16] buffer, simplifying GHASH() */ | ||
| 928 | uint8_t nonce[12 + 4]; /* +4 creates space for AES block counter */ | 927 | uint8_t nonce[12 + 4]; /* +4 creates space for AES block counter */ |
| 929 | uint8_t scratch[AES_BLOCK_SIZE]; //[16] | 928 | uint8_t scratch[AES_BLOCK_SIZE]; //[16] |
| 930 | //uint8_t authtag[AES_BLOCK_SIZE]; //[16] | 929 | //uint8_t authtag[AES_BLOCK_SIZE]; //[16] |
| @@ -935,14 +934,14 @@ static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size) | |||
| 935 | //aad[9] = TLS_MAJ; | 934 | //aad[9] = TLS_MAJ; |
| 936 | //aad[10] = TLS_MIN; | 935 | //aad[10] = TLS_MIN; |
| 937 | //aad[11] = size >> 8; | 936 | //aad[11] = size >> 8; |
| 938 | //aad[12] = size & 0xff; | 937 | ///* set aad[12], and clear aad[13..15] */ |
| 938 | //COUNTER(aad) = SWAP_LE32(size & 0xff); | ||
| 939 | 939 | ||
| 940 | //memcpy(aad, &tls->write_seq64_be, 8); | ||
| 940 | memcpy(nonce, tls->server_write_IV, 4); | 941 | memcpy(nonce, tls->server_write_IV, 4); |
| 941 | memcpy(nonce + 4, buf, 8); | 942 | memcpy(nonce + 4, buf, 8); |
| 942 | buf += 8; | 943 | buf += 8; |
| 943 | 944 | ||
| 944 | #define COUNTER(v) (*(uint32_t*)(v + 12)) | ||
| 945 | |||
| 946 | cnt = 1; | 945 | cnt = 1; |
| 947 | remaining = size; | 946 | remaining = size; |
| 948 | while (remaining != 0) { | 947 | while (remaining != 0) { |
| @@ -957,8 +956,7 @@ static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size) | |||
| 957 | remaining -= n; | 956 | remaining -= n; |
| 958 | } | 957 | } |
| 959 | 958 | ||
| 960 | ////optimize fixed sizes | 959 | //aesgcm_GHASH(tls->H, aad, tls->outbuf + OUTBUF_PFX, size, authtag); |
| 961 | //aesgcm_GHASH(tls->H, aad, sizeof(aad), tls->outbuf + OUTBUF_PFX, size, authtag, sizeof(authtag)); | ||
| 962 | //COUNTER(nonce) = htonl(1); | 960 | //COUNTER(nonce) = htonl(1); |
| 963 | //aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); | 961 | //aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); |
| 964 | //xorbuf(authtag, scratch, sizeof(authtag)); | 962 | //xorbuf(authtag, scratch, sizeof(authtag)); |
diff --git a/networking/tls_aesgcm.c b/networking/tls_aesgcm.c index eb32f4c05..1a7ddb2e2 100644 --- a/networking/tls_aesgcm.c +++ b/networking/tls_aesgcm.c | |||
| @@ -25,23 +25,26 @@ void FAST_FUNC xorbuf(void* buf, const void* mask, unsigned count) | |||
| 25 | b[i] ^= m[i]; | 25 | b[i] ^= m[i]; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | /* wolfssl-3.15.3/wolfcrypt/src/aes.c */ | 28 | /* from wolfssl-3.15.3/wolfcrypt/src/aes.c */ |
| 29 | 29 | ||
| 30 | static void FlattenSzInBits(byte* buf, word32 sz) | 30 | static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz) |
| 31 | { | 31 | { |
| 32 | /* Multiply the sz by 8 */ | 32 | /* Multiply the sz by 8 */ |
| 33 | word32 szHi = (sz >> (8*sizeof(sz) - 3)); | 33 | //bbox: these sizes are never even close to 2^32/8 |
| 34 | // word32 szHi = (sz >> (8*sizeof(sz) - 3)); | ||
| 34 | sz <<= 3; | 35 | sz <<= 3; |
| 35 | 36 | ||
| 36 | /* copy over the words of the sz into the destination buffer */ | 37 | /* copy over the words of the sz into the destination buffer */ |
| 37 | buf[0] = (szHi >> 24) & 0xff; | 38 | // buf[0] = (szHi >> 24) & 0xff; |
| 38 | buf[1] = (szHi >> 16) & 0xff; | 39 | // buf[1] = (szHi >> 16) & 0xff; |
| 39 | buf[2] = (szHi >> 8) & 0xff; | 40 | // buf[2] = (szHi >> 8) & 0xff; |
| 40 | buf[3] = szHi & 0xff; | 41 | // buf[3] = szHi & 0xff; |
| 41 | buf[4] = (sz >> 24) & 0xff; | 42 | move_to_unaligned32(buf, 0); |
| 42 | buf[5] = (sz >> 16) & 0xff; | 43 | // buf[4] = (sz >> 24) & 0xff; |
| 43 | buf[6] = (sz >> 8) & 0xff; | 44 | // buf[5] = (sz >> 16) & 0xff; |
| 44 | buf[7] = sz & 0xff; | 45 | // buf[6] = (sz >> 8) & 0xff; |
| 46 | // buf[7] = sz & 0xff; | ||
| 47 | move_to_unaligned32(buf + 4, SWAP_BE32(sz)); | ||
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | static void RIGHTSHIFTX(byte* x) | 50 | static void RIGHTSHIFTX(byte* x) |
| @@ -83,35 +86,47 @@ static void GMULT(byte* X, byte* Y) | |||
| 83 | XMEMCPY(X, Z, AES_BLOCK_SIZE); | 86 | XMEMCPY(X, Z, AES_BLOCK_SIZE); |
| 84 | } | 87 | } |
| 85 | 88 | ||
| 86 | void FAST_FUNC aesgcm_GHASH(byte* h, const byte* a, unsigned aSz, const byte* c, | 89 | //bbox: |
| 87 | unsigned cSz, byte* s, unsigned sSz) | 90 | // for TLS AES-GCM, a (which as AAD) is always 13 bytes long, and bbox code provides |
| 91 | // extra 3 zeroed bytes, making it a[16], or a[AES_BLOCK_SIZE]. | ||
| 92 | // Resulting auth tag in s is also always AES_BLOCK_SIZE bytes. | ||
| 93 | // | ||
| 94 | // This allows some simplifications. | ||
| 95 | #define aSz AES_BLOCK_SIZE | ||
| 96 | #define sSz AES_BLOCK_SIZE | ||
| 97 | void FAST_FUNC aesgcm_GHASH(byte* h, | ||
| 98 | const byte* a, //unsigned aSz, | ||
| 99 | const byte* c, unsigned cSz, | ||
| 100 | byte* s //, unsigned sSz | ||
| 101 | ) | ||
| 88 | { | 102 | { |
| 89 | byte x[AES_BLOCK_SIZE]; | 103 | byte x[AES_BLOCK_SIZE]; |
| 90 | byte scratch[AES_BLOCK_SIZE]; | 104 | byte scratch[AES_BLOCK_SIZE]; |
| 91 | word32 blocks, partial; | 105 | word32 blocks, partial; |
| 92 | //was: byte* h = aes->H; | 106 | //was: byte* h = aes->H; |
| 93 | 107 | ||
| 94 | XMEMSET(x, 0, AES_BLOCK_SIZE); | 108 | //XMEMSET(x, 0, AES_BLOCK_SIZE); |
| 95 | 109 | ||
| 96 | /* Hash in A, the Additional Authentication Data */ | 110 | /* Hash in A, the Additional Authentication Data */ |
| 97 | if (aSz != 0 && a != NULL) { | 111 | // if (aSz != 0 && a != NULL) { |
| 98 | blocks = aSz / AES_BLOCK_SIZE; | 112 | // blocks = aSz / AES_BLOCK_SIZE; |
| 99 | partial = aSz % AES_BLOCK_SIZE; | 113 | // partial = aSz % AES_BLOCK_SIZE; |
| 100 | while (blocks--) { | 114 | // while (blocks--) { |
| 101 | xorbuf(x, a, AES_BLOCK_SIZE); | 115 | //xorbuf(x, a, AES_BLOCK_SIZE); |
| 102 | GMULT(x, h); | 116 | XMEMCPY(x, a, AES_BLOCK_SIZE);// memcpy(x,a) = memset(x,0)+xorbuf(x,a) |
| 103 | a += AES_BLOCK_SIZE; | ||
| 104 | } | ||
| 105 | if (partial != 0) { | ||
| 106 | XMEMSET(scratch, 0, AES_BLOCK_SIZE); | ||
| 107 | XMEMCPY(scratch, a, partial); | ||
| 108 | xorbuf(x, scratch, AES_BLOCK_SIZE); | ||
| 109 | GMULT(x, h); | 117 | GMULT(x, h); |
| 110 | } | 118 | // a += AES_BLOCK_SIZE; |
| 111 | } | 119 | // } |
| 120 | // if (partial != 0) { | ||
| 121 | // XMEMSET(scratch, 0, AES_BLOCK_SIZE); | ||
| 122 | // XMEMCPY(scratch, a, partial); | ||
| 123 | // xorbuf(x, scratch, AES_BLOCK_SIZE); | ||
| 124 | // GMULT(x, h); | ||
| 125 | // } | ||
| 126 | // } | ||
| 112 | 127 | ||
| 113 | /* Hash in C, the Ciphertext */ | 128 | /* Hash in C, the Ciphertext */ |
| 114 | if (cSz != 0 && c != NULL) { | 129 | if (cSz != 0 /*&& c != NULL*/) { |
| 115 | blocks = cSz / AES_BLOCK_SIZE; | 130 | blocks = cSz / AES_BLOCK_SIZE; |
| 116 | partial = cSz % AES_BLOCK_SIZE; | 131 | partial = cSz % AES_BLOCK_SIZE; |
| 117 | while (blocks--) { | 132 | while (blocks--) { |
diff --git a/networking/tls_aesgcm.h b/networking/tls_aesgcm.h index a71eced54..75694f3fa 100644 --- a/networking/tls_aesgcm.h +++ b/networking/tls_aesgcm.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | void xorbuf(void* buf, const void* mask, unsigned count) FAST_FUNC; | 7 | void xorbuf(void* buf, const void* mask, unsigned count) FAST_FUNC; |
| 8 | 8 | ||
| 9 | void aesgcm_GHASH(uint8_t* h, | 9 | void aesgcm_GHASH(uint8_t* h, |
| 10 | const uint8_t* a, unsigned aSz, | 10 | const uint8_t* a, //unsigned aSz, |
| 11 | const uint8_t* c, unsigned cSz, | 11 | const uint8_t* c, unsigned cSz, |
| 12 | uint8_t* s, unsigned sSz | 12 | uint8_t* s //, unsigned sSz |
| 13 | ) FAST_FUNC; | 13 | ) FAST_FUNC; |
