stun

simple point to point tunnel
git clone git://git.2f30.org/stun
Log | Files | Refs | README

commit b59586b4ba0af5a83f144466a9fa1d72ff2d2006
parent 9f259643eb44104b25a0c5039466d9938f618fb3
Author: sin <sin@2f30.org>
Date:   Tue, 29 Mar 2016 19:19:18 +0100

clean up crypto code

Diffstat:
Mstun.c | 78+++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 41 insertions(+), 37 deletions(-)

diff --git a/stun.c b/stun.c @@ -27,7 +27,7 @@ * All tunneled traffic is encapsulated inside the TCP payload. * The packet format is shown below: * - * [PAYLOAD LENGTH][PAYLOAD] + * [UNPADDED PAYLOAD LENGTH][PADDED PAYLOAD] * * The payload is encrypted and padded to 16 bytes. The payload length is a * two-octet field that describes the length of the unpadded payload. @@ -197,10 +197,13 @@ int aesinit(EVP_CIPHER_CTX *ectx, EVP_CIPHER_CTX *dctx) { EVP_CIPHER_CTX_init(ectx); - EVP_CIPHER_CTX_init(dctx); + EVP_EncryptInit_ex(ectx, EVP_aes_256_cbc(), NULL, NULL, NULL); EVP_EncryptInit_ex(ectx, EVP_aes_256_cbc(), NULL, aeskey, aesiv); - EVP_DecryptInit_ex(dctx, EVP_aes_256_cbc(), NULL, aeskey, aesiv); EVP_CIPHER_CTX_set_padding(ectx, 0); + + EVP_CIPHER_CTX_init(dctx); + EVP_DecryptInit_ex(dctx, EVP_aes_256_cbc(), NULL, NULL, NULL); + EVP_DecryptInit_ex(dctx, EVP_aes_256_cbc(), NULL, aeskey, aesiv); EVP_CIPHER_CTX_set_padding(dctx, 0); return 0; } @@ -213,23 +216,21 @@ aesterm(EVP_CIPHER_CTX *ectx, EVP_CIPHER_CTX *dctx) } int -aesenc(EVP_CIPHER_CTX *ectx, unsigned char *ciphertext, - unsigned char *plaintext, int len) +aesenc(EVP_CIPHER_CTX *ctx, unsigned char *ct, unsigned char *pt, int plen) { int clen; - if (EVP_EncryptUpdate(ectx, ciphertext, &clen, plaintext, len) != 1) + if (EVP_EncryptUpdate(ctx, ct, &clen, pt, plen) != 1) logerr("EVP_EncryptUpdate failed"); return clen; } int -aesdec(EVP_CIPHER_CTX *dctx, unsigned char *plaintext, - unsigned char *ciphertext, int len) +aesdec(EVP_CIPHER_CTX *ctx, unsigned char *pt, unsigned char *ct, int clen) { int plen; - if (EVP_DecryptUpdate(dctx, plaintext, &plen, ciphertext, len) != 1) + if (EVP_DecryptUpdate(ctx, pt, &plen, ct, clen) != 1) logerr("EVP_DecryptUpdate failed"); return plen; } @@ -427,24 +428,6 @@ writeall(int fd, void *buf, int len) } int -writenet(int fd, unsigned char *buf, int len) -{ - unsigned char encbuf[MTU + AES_BLOCK_SIZE + HDRLEN]; - - /* fill padding with random bytes */ - if (padlen(len, AES_BLOCK_SIZE) > 0) - arc4random_buf(&encbuf[HDRLEN + len], - padlen(len, AES_BLOCK_SIZE)); - - aesenc(&enc, &encbuf[HDRLEN], buf, padto(len, AES_BLOCK_SIZE)); - /* insert unpadded payload len at the start of the packet */ - pack16(encbuf, len); - /* calculate total size of packet and send it on the wire */ - len = padto(len, AES_BLOCK_SIZE) + HDRLEN; - return writeall(fd, encbuf, len); -} - -int readall(int fd, void *buf, int len) { unsigned char *p = buf; @@ -466,28 +449,49 @@ readall(int fd, void *buf, int len) } int -readnet(int fd, unsigned char *buf, int len) +writenet(int fd, unsigned char *pt, int len) +{ + unsigned char payload[MTU + AES_BLOCK_SIZE]; + unsigned char hdr[HDRLEN]; + unsigned char pkt[sizeof(hdr) + sizeof(payload)]; + + /* fill padding with random bytes */ + if (padlen(len, AES_BLOCK_SIZE) > 0) + arc4random_buf(&payload[len], padlen(len, AES_BLOCK_SIZE)); + + pack16(hdr, len); + len = padto(len, AES_BLOCK_SIZE); + aesenc(&enc, payload, pt, len); + memcpy(pkt, hdr, HDRLEN); + memcpy(&pkt[HDRLEN], payload, len); + len += HDRLEN; + return writeall(fd, pkt, len); +} + +int +readnet(int fd, unsigned char *pt, int len) { - unsigned char encbuf[MTU + AES_BLOCK_SIZE + HDRLEN]; + unsigned char payload[MTU + AES_BLOCK_SIZE]; + unsigned char hdr[HDRLEN]; int n, pktlen, paddedlen; /* read unpadded packet length */ - n = readall(fd, encbuf, HDRLEN); + n = readall(fd, hdr, HDRLEN); if (n <= 0) return n; - pktlen = unpack16(encbuf); + pktlen = unpack16(hdr); pktlen &= PKTLENMASK; paddedlen = padto(pktlen, AES_BLOCK_SIZE); /* discard bad packets */ - if (pktlen > len || paddedlen > MTU + AES_BLOCK_SIZE) { + if (pktlen > len || paddedlen > sizeof(payload)) { while (paddedlen) { - if (paddedlen > MTU + AES_BLOCK_SIZE) - len = MTU + AES_BLOCK_SIZE; + if (paddedlen > sizeof(payload)) + len = sizeof(payload); else len = paddedlen; - n = readall(fd, encbuf, len); + n = readall(fd, payload, len); if (n <= 0) break; paddedlen -= n; @@ -496,11 +500,11 @@ readnet(int fd, unsigned char *buf, int len) } /* read encrypted payload */ - n = readall(fd, &encbuf[HDRLEN], paddedlen); + n = readall(fd, payload, paddedlen); if (n <= 0) return n; - aesdec(&dec, buf, &encbuf[HDRLEN], paddedlen); + aesdec(&dec, pt, payload, paddedlen); return pktlen; }