Annotation of embedaddon/strongswan/src/libtls/tls_prf.c, revision 1.1.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>