X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fopenssl%2Fprf.c;h=ddad522f71814db7045efddf32808fc6f749cb0b;hb=cfc9fee931c70554353ce6c4acc3407baac08745;hp=b37efdf04be864ae28eba1dab1bf164d4ba724cb;hpb=70a1a5594af5d4e6a364186b42ba4e34c676009b;p=tinc diff --git a/src/openssl/prf.c b/src/openssl/prf.c index b37efdf0..ddad522f 100644 --- a/src/openssl/prf.c +++ b/src/openssl/prf.c @@ -1,6 +1,6 @@ /* prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011-2013 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,25 +17,30 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include "digest.h" -#include "prf.h" +#include "../digest.h" +#include "../prf.h" /* Generate key material from a master secret and a seed, based on RFC 4346 section 5. We use SHA512 instead of MD5 and SHA1. */ -static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { - digest_t digest; +static bool prf_xor(int nid, const uint8_t *secret, size_t secretlen, uint8_t *seed, size_t seedlen, uint8_t *out, size_t outlen) { + digest_t digest = {0}; - if(!digest_open_by_nid(&digest, nid, -1)) + if(!digest_open_by_nid(&digest, nid, DIGEST_ALGO_SIZE)) { + digest_close(&digest); return false; + } - if(!digest_set_key(&digest, secret, secretlen)) + if(!digest_set_key(&digest, secret, secretlen)) { + digest_close(&digest); return false; + } size_t len = digest_length(&digest); @@ -43,31 +48,40 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, s It consists of the previous HMAC result plus the seed. */ - char data[len + seedlen]; + char *data = alloca(len + seedlen); memset(data, 0, len); memcpy(data + len, seed, seedlen); - char hash[len]; + uint8_t *hash = alloca(len); while(outlen > 0) { /* Inner HMAC */ - digest_create(&digest, data, len + seedlen, data); + if(!digest_create(&digest, data, len + seedlen, data)) { + digest_close(&digest); + return false; + } /* Outer HMAC */ - digest_create(&digest, data, len + seedlen, hash); + if(!digest_create(&digest, data, len + seedlen, hash)) { + digest_close(&digest); + return false; + } /* XOR the results of the outer HMAC into the out buffer */ - for(int i = 0; i < len && i < outlen; i++) + size_t i; + + for(i = 0; i < len && i < outlen; i++) { *out++ ^= hash[i]; + } - outlen -= len; + outlen -= i; } digest_close(&digest); return true; } -bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { +bool prf(const uint8_t *secret, size_t secretlen, uint8_t *seed, size_t seedlen, uint8_t *out, size_t outlen) { /* This construction allows us to easily switch back to a scheme where the PRF is calculated using two different digest algorithms. */ memset(out, 0, outlen);