Annotation of embedaddon/strongswan/src/libtls/tls_prf.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2010 Martin Willi
! 3: * Copyright (C) 2010 revosec AG
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "tls_prf.h"
! 17:
! 18: typedef struct private_tls_prf12_t private_tls_prf12_t;
! 19:
! 20: #include <library.h>
! 21:
! 22: /**
! 23: * Private data of an tls_prf_t object.
! 24: */
! 25: struct private_tls_prf12_t {
! 26:
! 27: /**
! 28: * Public tls_prf_t interface.
! 29: */
! 30: tls_prf_t public;
! 31:
! 32: /**
! 33: * Underlying primitive PRF
! 34: */
! 35: prf_t *prf;
! 36: };
! 37:
! 38: METHOD(tls_prf_t, set_key12, bool,
! 39: private_tls_prf12_t *this, chunk_t key)
! 40: {
! 41: return this->prf->set_key(this->prf, key);
! 42: }
! 43:
! 44: /**
! 45: * The P_hash function as in TLS 1.0/1.2
! 46: */
! 47: static bool p_hash(prf_t *prf, char *label, chunk_t seed, size_t block_size,
! 48: size_t bytes, char *out)
! 49: {
! 50: char buf[block_size], abuf[block_size];
! 51: chunk_t a;
! 52:
! 53: /* seed = label + seed */
! 54: seed = chunk_cata("cc", chunk_create(label, strlen(label)), seed);
! 55: /* A(0) = seed */
! 56: a = seed;
! 57:
! 58: while (TRUE)
! 59: {
! 60: /* A(i) = HMAC_hash(secret, A(i-1)) */
! 61: if (!prf->get_bytes(prf, a, abuf))
! 62: {
! 63: return FALSE;
! 64: }
! 65: a = chunk_from_thing(abuf);
! 66: /* HMAC_hash(secret, A(i) + seed) */
! 67: if (!prf->get_bytes(prf, a, NULL) ||
! 68: !prf->get_bytes(prf, seed, buf))
! 69: {
! 70: return FALSE;
! 71: }
! 72:
! 73: if (bytes <= block_size)
! 74: {
! 75: memcpy(out, buf, bytes);
! 76: break;
! 77: }
! 78: memcpy(out, buf, block_size);
! 79: out += block_size;
! 80: bytes -= block_size;
! 81: }
! 82: return TRUE;
! 83: }
! 84:
! 85: METHOD(tls_prf_t, get_bytes12, bool,
! 86: private_tls_prf12_t *this, char *label, chunk_t seed,
! 87: size_t bytes, char *out)
! 88: {
! 89: return p_hash(this->prf, label, seed, this->prf->get_block_size(this->prf),
! 90: bytes, out);
! 91: }
! 92:
! 93: METHOD(tls_prf_t, destroy12, void,
! 94: private_tls_prf12_t *this)
! 95: {
! 96: this->prf->destroy(this->prf);
! 97: free(this);
! 98: }
! 99:
! 100: /**
! 101: * See header
! 102: */
! 103: tls_prf_t *tls_prf_create_12(pseudo_random_function_t prf)
! 104: {
! 105: private_tls_prf12_t *this;
! 106:
! 107: INIT(this,
! 108: .public = {
! 109: .set_key = _set_key12,
! 110: .get_bytes = _get_bytes12,
! 111: .destroy = _destroy12,
! 112: },
! 113: .prf = lib->crypto->create_prf(lib->crypto, prf),
! 114: );
! 115: if (!this->prf)
! 116: {
! 117: free(this);
! 118: return NULL;
! 119: }
! 120: return &this->public;
! 121: }
! 122:
! 123:
! 124: typedef struct private_tls_prf10_t private_tls_prf10_t;
! 125:
! 126: /**
! 127: * Private data of an tls_prf_t object.
! 128: */
! 129: struct private_tls_prf10_t {
! 130:
! 131: /**
! 132: * Public tls_prf_t interface.
! 133: */
! 134: tls_prf_t public;
! 135:
! 136: /**
! 137: * Underlying MD5 PRF
! 138: */
! 139: prf_t *md5;
! 140:
! 141: /**
! 142: * Underlying SHA1 PRF
! 143: */
! 144: prf_t *sha1;
! 145: };
! 146:
! 147: METHOD(tls_prf_t, set_key10, bool,
! 148: private_tls_prf10_t *this, chunk_t key)
! 149: {
! 150: size_t len = key.len / 2 + key.len % 2;
! 151:
! 152: return this->md5->set_key(this->md5, chunk_create(key.ptr, len)) &&
! 153: this->sha1->set_key(this->sha1, chunk_create(key.ptr + key.len - len,
! 154: len));
! 155: }
! 156:
! 157: METHOD(tls_prf_t, get_bytes10, bool,
! 158: private_tls_prf10_t *this, char *label, chunk_t seed,
! 159: size_t bytes, char *out)
! 160: {
! 161: char buf[bytes];
! 162:
! 163: if (!p_hash(this->md5, label, seed, this->md5->get_block_size(this->md5),
! 164: bytes, out) ||
! 165: !p_hash(this->sha1, label, seed, this->sha1->get_block_size(this->sha1),
! 166: bytes, buf))
! 167: {
! 168: return FALSE;
! 169: }
! 170: memxor(out, buf, bytes);
! 171: return TRUE;
! 172: }
! 173:
! 174: METHOD(tls_prf_t, destroy10, void,
! 175: private_tls_prf10_t *this)
! 176: {
! 177: DESTROY_IF(this->md5);
! 178: DESTROY_IF(this->sha1);
! 179: free(this);
! 180: }
! 181:
! 182: /**
! 183: * See header
! 184: */
! 185: tls_prf_t *tls_prf_create_10()
! 186: {
! 187: private_tls_prf10_t *this;
! 188:
! 189: INIT(this,
! 190: .public = {
! 191: .set_key = _set_key10,
! 192: .get_bytes = _get_bytes10,
! 193: .destroy = _destroy10,
! 194: },
! 195: .md5 = lib->crypto->create_prf(lib->crypto, PRF_HMAC_MD5),
! 196: .sha1 = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA1),
! 197: );
! 198: if (!this->md5 || !this->sha1)
! 199: {
! 200: destroy10(this);
! 201: return NULL;
! 202: }
! 203: return &this->public;
! 204: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>