X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fopenssl%2Fprf.c;h=4f5a52befc65a98bbaf8338aa7dda5d4fe2a3d11;hp=df7f445c4940adda32449a944009cb8febda2a85;hb=d4410d0cce40929db9a0ce7042ef962f1867234d;hpb=b99656d84a88dad7935d5981fcdb43a5b2bfa417 diff --git a/src/openssl/prf.c b/src/openssl/prf.c index df7f445c..4f5a52be 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 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 and Whirlpool instead of MD5 and SHA1. + We use SHA512 instead of MD5 and SHA1. */ -static bool prf_xor(int nid, char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { - digest_t digest; - - if(!digest_open_by_nid(&digest, nid, -1)) +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 = digest_open_by_nid(nid, -1); + + if(!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); + size_t len = digest_length(digest); /* Data is what the "inner" HMAC function processes. It consists of the previous HMAC result plus the seed. @@ -49,10 +54,16 @@ static bool prf_xor(int nid, char *secret, size_t secretlen, char *seed, size_t 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++) @@ -61,16 +72,13 @@ static bool prf_xor(int nid, char *secret, size_t secretlen, char *seed, size_t outlen -= len; } - digest_close(&digest); + digest_close(digest); return true; } -bool prf(char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - /* Split secret in half, generate outlen bits with two different hash algorithms, - and XOR the results. */ - +bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *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); - return prf_xor(NID_sha512, secret, (secretlen + 1) / 2, seed, seedlen, out, outlen) - && prf_xor(NID_whirlpool, secret + secretlen / 2, (secretlen + 1) / 2, seed, seedlen, out, outlen); + return prf_xor(NID_sha512, secret, secretlen, seed, seedlen, out, outlen); }