commit ce49b50087db948799ab4ac752a917517a704f06
parent 5a92ce669539b031d2b93ca79271b23babc21761
Author: sin <sin@2f30.org>
Date: Wed, 22 Mar 2017 12:17:40 +0000
Switch to libsodium
Diffstat:
8 files changed, 58 insertions(+), 119 deletions(-)
diff --git a/auth.c b/auth.c
@@ -12,7 +12,7 @@ int
challenge(int netfd)
{
unsigned char buf[sizeof(uint64_t)];
- size_t outlen;
+ unsigned long long outlen;
struct pollfd pfd[1];
uint64_t n, reply;
int ret;
@@ -54,7 +54,7 @@ int
response(int netfd)
{
unsigned char buf[sizeof(uint64_t)];
- size_t outlen;
+ unsigned long long outlen;
struct pollfd pfd[1];
uint64_t reply;
int ret;
diff --git a/config.mk b/config.mk
@@ -8,11 +8,11 @@ LIB = /usr/local/lib
# BSD
CFLAGS = -std=c99 -Wall -I$(INC)
-LDLIBS = -L$(LIB) -lcrypto
+LDLIBS = -L$(LIB) -lsodium
EXTRAOBJ = dev_bsd.o
# Linux
#CFLAGS = -std=c99 -Wall -I$(INC)
#CPPFLAGS = -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
-#LDLIBS = -L$(LIB) -lcrypto -lbsd
+#LDLIBS = -L$(LIB) -lsodium -lbsd
#EXTRAOBJ = dev_linux.o
diff --git a/crypto.c b/crypto.c
@@ -1,90 +1,57 @@
#include <string.h>
-#include <openssl/evp.h>
+#include <sodium.h>
#include "stun.h"
-static EVP_AEAD_CTX ectx, dctx;
-static const EVP_AEAD *aead;
-static unsigned char key[EVP_MAX_KEY_LENGTH];
-
-static struct cipher {
- const char *name;
- const EVP_AEAD *(*aeadfn)(void);
-} ciphers[] = {
- { "aes-128-gcm", EVP_aead_aes_128_gcm },
- { "aes-256-gcm", EVP_aead_aes_256_gcm },
- { "chacha20-poly1305", EVP_aead_chacha20_poly1305 },
- { NULL, NULL }
-};
+static unsigned char salt[crypto_pwhash_SALTBYTES];
+static unsigned char key[crypto_aead_chacha20poly1305_IETF_KEYBYTES];
void
-listciphers(void)
+cryptoinit(void)
{
- struct cipher *cp;
-
- for (cp = ciphers; cp->name; cp++)
- puts(cp->name);
-}
-
-void
-setcipher(char *name)
-{
- struct cipher *cp;
-
- for (cp = ciphers; cp->name; cp++) {
- if (strcmp(cp->name, name) == 0) {
- aead = (*cp->aeadfn)();
- return;
- }
- }
- fatalx("unknown cipher: %s", name);
+ if (sodium_init() == -1)
+ fatalx("failed to initialize crypto engine");
}
void
derivekey(char *pw)
{
- if (!PKCS5_PBKDF2_HMAC_SHA1(pw, strlen(pw), NULL, 0, NROUNDS,
- EVP_AEAD_key_length(aead), key))
- fatalx("PKCS5_PBKDF2_HMAC_SHA1 failed");
-}
-
-void
-cryptoinit(void)
-{
- if (!EVP_AEAD_CTX_init(&ectx, aead, key, EVP_AEAD_key_length(aead),
- EVP_AEAD_DEFAULT_TAG_LENGTH, NULL) ||
- !EVP_AEAD_CTX_init(&dctx, aead, key, EVP_AEAD_key_length(aead),
- EVP_AEAD_DEFAULT_TAG_LENGTH, NULL))
- fatalx("EVP_AEAD_CTX_init failed");
+ memset(salt, 0, sizeof(salt)); /* XXX */
+ if (crypto_pwhash(key, sizeof(key), pw, strlen(pw), salt,
+ crypto_pwhash_OPSLIMIT_INTERACTIVE,
+ crypto_pwhash_MEMLIMIT_INTERACTIVE,
+ crypto_pwhash_ALG_DEFAULT) != 0)
+ fatalx("failed to derive key");
}
size_t
cryptononcelen(void)
{
- return EVP_AEAD_nonce_length(aead);
+ return crypto_aead_chacha20poly1305_IETF_NPUBBYTES;
}
size_t
cryptotaglen(void)
{
- return EVP_AEAD_max_tag_len(aead);
+ return crypto_aead_chacha20poly1305_ietf_ABYTES;
}
-int
-cryptoseal(unsigned char *out, size_t *outlen, size_t maxoutlen,
- const unsigned char *nonce, size_t noncelen, const unsigned char *in,
- size_t inlen, const unsigned char *ad, size_t adlen)
+int cryptoseal(unsigned char *c, unsigned long long *clen,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *npub)
{
- return EVP_AEAD_CTX_seal(&ectx, out, outlen, maxoutlen, nonce, noncelen,
- in, inlen, ad, adlen);
+ return crypto_aead_chacha20poly1305_ietf_encrypt(c, clen, m, mlen,
+ ad, adlen, NULL,
+ npub, key);
}
-int
-cryptoopen(unsigned char *out, size_t *outlen, size_t maxoutlen,
- const unsigned char *nonce, size_t noncelen, const unsigned char *in,
- size_t inlen, const unsigned char *ad, size_t adlen)
+int cryptoopen(unsigned char *m, unsigned long long *mlen,
+ const unsigned char *c, unsigned long long clen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *npub)
{
- return EVP_AEAD_CTX_open(&dctx, out, outlen, maxoutlen, nonce, noncelen,
- in, inlen, ad, adlen);
+ return crypto_aead_chacha20poly1305_ietf_decrypt(m, mlen, NULL, c, clen,
+ ad, adlen, npub, key);
}
diff --git a/netpkt.c b/netpkt.c
@@ -42,10 +42,11 @@ static size_t taglen;
static int rxstate;
int
-netwrite(int fd, unsigned char *pt, size_t ptlen, size_t *outlen)
+netwrite(int fd, unsigned char *pt, unsigned long long ptlen,
+ unsigned long long *outlen)
{
unsigned char *p = wbuf;
- size_t buflen = noncelen + HDRLEN + ptlen + taglen;
+ unsigned long long buflen = noncelen + HDRLEN + ptlen + taglen;
int n, total = 0;
if (buflen > maxbuflen) {
@@ -55,13 +56,11 @@ netwrite(int fd, unsigned char *pt, size_t ptlen, size_t *outlen)
arc4random_buf(wbuf, noncelen);
pack16(&wbuf[noncelen], ptlen);
- if (!cryptoseal(&wbuf[noncelen + HDRLEN], outlen,
- ptlen + taglen, wbuf, noncelen,
- pt, ptlen, &wbuf[noncelen], HDRLEN)) {
+ if (cryptoseal(&wbuf[noncelen + HDRLEN], outlen,
+ pt, ptlen, &wbuf[noncelen], HDRLEN, wbuf) != 0) {
logwarnx("cryptoseal failed");
return -1;
}
- *outlen = ptlen;
/* spin until all data is written */
while (buflen > 0) {
@@ -80,9 +79,10 @@ netwrite(int fd, unsigned char *pt, size_t ptlen, size_t *outlen)
}
int
-netread(int fd, unsigned char *pt, size_t ptlen, size_t *outlen)
+netread(int fd, unsigned char *pt, unsigned long long ptlen,
+ unsigned long long *outlen)
{
- size_t buflen = noncelen + HDRLEN + ptlen + taglen;
+ unsigned long long buflen = noncelen + HDRLEN + ptlen + taglen;
int n, ctlen;
if (buflen > maxbuflen) {
@@ -142,10 +142,9 @@ netread(int fd, unsigned char *pt, size_t ptlen, size_t *outlen)
break;
case RXDECRYPT:
rxstate = RXINITIAL;
- if (!cryptoopen(pt, outlen, ptlen, rbuf, noncelen,
- &rbuf[noncelen + HDRLEN],
- rbuftotal - noncelen - HDRLEN,
- &rbuf[noncelen], HDRLEN)) {
+ if (cryptoopen(pt, outlen, &rbuf[noncelen + HDRLEN],
+ rbuftotal - noncelen - HDRLEN,
+ &rbuf[noncelen], HDRLEN, rbuf) != 0) {
logwarnx("cryptoopen failed");
return PKTPARTIAL;
}
diff --git a/stun.8 b/stun.8
@@ -1,4 +1,4 @@
-.Dd April 21, 2016
+.Dd March 22, 2017
.Dt STUN 8
.Os
.Sh NAME
@@ -12,7 +12,6 @@
.Op Fl b Ar address
.Op Fl p Ar port
.Op Fl t Ar devtype
-.Op Fl c Ar cipher
.Op Fl u Ar user
.Ar interface
.Nm stun
@@ -21,7 +20,6 @@
.Fl h Ar host
.Op Fl p Ar port
.Op Fl t Ar devtype
-.Op Fl c Ar cipher
.Op Fl u Ar user
.Ar interface
.Sh DESCRIPTION
@@ -59,12 +57,6 @@ Connect to specified
Select the tunnel
.Ar device type .
The two available device types are TUN and TAP. The default is TUN.
-.It Fl c Ar cipher
-Select the given
-.Ar cipher .
-If the argument is ? then
-.Nm
-will list the available ciphers. The default cipher is chacha20-poly1305.
.It Fl u Ar user
Drop privileges to the specified
.Ar user .
diff --git a/stun.c b/stun.c
@@ -9,15 +9,6 @@
* connected to the server at any time. Routing between clients is handled
* by the networking stack on the server side.
*
- * stun supports multiple AEAD ciphers:
- *
- * aes-128-gcm
- * aes-256-gcm
- * chacha20-poly1305
- *
- * The default cipher is chacha20-poly1305. The key is derived with
- * PBKDF.
- *
* When a client connects there is a mutual challenge-response phase
* as shown below:
*
@@ -54,7 +45,6 @@ char *argv0;
char *bindaddr;
char *host;
char *port = DEFPORT;
-char *cipher = DEFCIPHER;
int devtype = TUNDEV;
int aftype = AF_INET;
int sflag;
@@ -62,8 +52,8 @@ int sflag;
void
usage(void)
{
- fprintf(stderr, "usage: stun [-46] [-d] -s [-b address] [-p port] [-t devtype] [-c cipher] [-u user] interface\n");
- fprintf(stderr, " stun [-46] [-d] -h host [-p port] [-t devtype] [-c cipher] [-u user] interface\n");
+ fprintf(stderr, "usage: stun [-46] [-d] -s [-b address] [-p port] [-t devtype] [-u user] interface\n");
+ fprintf(stderr, " stun [-46] [-d] -h host [-p port] [-t devtype] [-u user] interface\n");
exit(1);
}
@@ -106,13 +96,6 @@ main(int argc, char *argv[])
else
usage();
break;
- case 'c':
- cipher = EARGF(usage());
- if (strcmp(cipher, "?") == 0) {
- listciphers();
- return 0;
- }
- break;
case 'u':
user = EARGF(usage());
break;
@@ -140,9 +123,8 @@ main(int argc, char *argv[])
/* initialize crypto engine */
if (!(pw = getenv("STUNPW")))
fatalx("STUNPW is not set");
- setcipher(cipher);
- derivekey(pw);
cryptoinit();
+ derivekey(pw);
memset(pw, 0, strlen(pw));
/* initialize networking engine */
diff --git a/stun.h b/stun.h
@@ -10,7 +10,6 @@
#define MAXPAYLOADLEN 1404
#define NROUNDS 100000
#define DEFPORT "12080"
-#define DEFCIPHER "chacha20-poly1305"
enum {
PKTFAILED,
@@ -39,18 +38,18 @@ int response(int);
int clientconnect(char *, char *);
/* crypto.c */
-void listciphers(void);
-void setcipher(char *);
-void derivekey(char *);
void cryptoinit(void);
+void derivekey(char *);
size_t cryptononcelen(void);
size_t cryptotaglen(void);
-int cryptoseal(unsigned char *, size_t *, size_t, const unsigned char *,
- size_t, const unsigned char *, size_t, const unsigned char *,
- size_t);
-int cryptoopen(unsigned char *, size_t *, size_t, const unsigned char *,
- size_t, const unsigned char *, size_t, const unsigned char *,
- size_t);
+int cryptoseal(unsigned char *, unsigned long long *,
+ const unsigned char *, unsigned long long,
+ const unsigned char *, unsigned long long,
+ const unsigned char *);
+int cryptoopen(unsigned char *, unsigned long long *,
+ const unsigned char *, unsigned long long,
+ const unsigned char *, unsigned long long,
+ const unsigned char *);
/* dev_*.c */
int devopen(char *);
@@ -67,8 +66,8 @@ void fatal(char *, ...);
void fatalx(char *, ...);
/* netpkt.c */
-int netwrite(int, unsigned char *, size_t, size_t *);
-int netread(int, unsigned char *, size_t, size_t *);
+int netwrite(int, unsigned char *, unsigned long long, unsigned long long *);
+int netread(int, unsigned char *, unsigned long long, unsigned long long *);
void netreset(void);
void netinit(void);
diff --git a/tunnel.c b/tunnel.c
@@ -6,7 +6,7 @@ int
tunnel(int netfd, int devfd)
{
unsigned char buf[MAXPAYLOADLEN];
- size_t outlen;
+ unsigned long long outlen;
struct pollfd pfd[2];
int n;