From 5b45524c5114065f26adfdfb04eb664afaf1e433 Mon Sep 17 00:00:00 2001 From: thorkill Date: Fri, 28 Apr 2017 10:21:13 +0200 Subject: [PATCH] Added sanity check for the keylength to prevent heap-buffer-overflow in chacha_keysetup() --- src/chacha-poly1305/chacha-poly1305.c | 7 +++++-- src/chacha-poly1305/chacha-poly1305.h | 2 +- src/sptps.c | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/chacha-poly1305/chacha-poly1305.c b/src/chacha-poly1305/chacha-poly1305.c index bd5cb2c4..bc5fc2be 100644 --- a/src/chacha-poly1305/chacha-poly1305.c +++ b/src/chacha-poly1305/chacha-poly1305.c @@ -13,7 +13,7 @@ struct chacha_poly1305_ctx { chacha_poly1305_ctx_t *chacha_poly1305_init(void) { - chacha_poly1305_ctx_t *ctx = xzalloc(sizeof *ctx); + chacha_poly1305_ctx_t *ctx = (chacha_poly1305_ctx_t *)xzalloc(sizeof *ctx); return ctx; } @@ -22,8 +22,11 @@ void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) free(ctx); } -bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key) +bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key, size_t keylen) { + if (keylen < CHACHA_POLY1305_KEYLEN) + return false; + chacha_keysetup(&ctx->main_ctx, key, 256); chacha_keysetup(&ctx->header_ctx, key + 32, 256); return true; diff --git a/src/chacha-poly1305/chacha-poly1305.h b/src/chacha-poly1305/chacha-poly1305.h index af7eaf5e..6f74f0bd 100644 --- a/src/chacha-poly1305/chacha-poly1305.h +++ b/src/chacha-poly1305/chacha-poly1305.h @@ -7,7 +7,7 @@ typedef struct chacha_poly1305_ctx chacha_poly1305_ctx_t; extern chacha_poly1305_ctx_t *chacha_poly1305_init(void); extern void chacha_poly1305_exit(chacha_poly1305_ctx_t *); -extern bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key); +extern bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key, size_t); extern bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen); extern bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen); diff --git a/src/sptps.c b/src/sptps.c index 56e24397..dfac4fff 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -248,10 +248,10 @@ static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { return error(s, EIO, "Invalid ACK record length"); if(s->initiator) { - if(!chacha_poly1305_set_key(s->incipher, s->key)) + if(!chacha_poly1305_set_key(s->incipher, s->key, 2 * CHACHA_POLY1305_KEYLEN)) return error(s, EINVAL, "Failed to set counter"); } else { - if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN)) + if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN, 2 * CHACHA_POLY1305_KEYLEN)) return error(s, EINVAL, "Failed to set counter"); } @@ -334,10 +334,10 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { // TODO: only set new keys after ACK has been set/received if(s->initiator) { - if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) + if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN, 2 * CHACHA_POLY1305_KEYLEN)) return error(s, EINVAL, "Failed to set key"); } else { - if(!chacha_poly1305_set_key(s->outcipher, s->key)) + if(!chacha_poly1305_set_key(s->outcipher, s->key, 2 * CHACHA_POLY1305_KEYLEN)) return error(s, EINVAL, "Failed to set key"); }