Annotation of embedaddon/strongswan/src/libstrongswan/crypto/prf_plus.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2005-2006 Martin Willi
3: * Copyright (C) 2005 Jan Hutter
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include <string.h>
18:
19: #include "prf_plus.h"
20:
21: typedef struct private_prf_plus_t private_prf_plus_t;
22:
23: typedef bool (*apply_prf_t)(private_prf_plus_t *this);
24:
25: /**
26: * Private data of an prf_plus_t object.
27: *
28: */
29: struct private_prf_plus_t {
30:
31: /**
32: * Public interface of prf_plus_t.
33: */
34: prf_plus_t public;
35:
36: /**
37: * PRF to use.
38: */
39: prf_t *prf;
40:
41: /**
42: * Initial seed.
43: */
44: chunk_t seed;
45:
46: /**
47: * Octet which will be appended to the seed if a counter is used.
48: */
49: uint8_t counter;
50:
51: /**
52: * Already given out bytes in current buffer.
53: */
54: size_t used;
55:
56: /**
57: * Buffer to store current PRF result.
58: */
59: chunk_t buffer;
60:
61: /**
62: * The prf application method depending on whether a counter is used.
63: */
64: apply_prf_t apply_prf;
65: };
66:
67: /**
68: * Apply the PRF using the running counter
69: */
70: static bool apply_prf_counter(private_prf_plus_t *this)
71: {
72: if (!this->prf->get_bytes(this->prf, this->seed, NULL) ||
73: !this->prf->get_bytes(this->prf, chunk_from_thing(this->counter),
74: this->buffer.ptr))
75: {
76: return FALSE;
77: }
78: this->counter++;
79: if (!this->counter)
80: { /* according to RFC 7296, section 2.13, prf+ is undefined once the
81: * counter wrapped, so let's fail for future calls */
82: this->apply_prf = (void*)return_false;
83: }
84: return TRUE;
85: }
86:
87: /**
88: * Apply the PRF using the running counter
89: */
90: static bool apply_prf(private_prf_plus_t *this)
91: {
92: return this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr);
93: }
94:
95: METHOD(prf_plus_t, get_bytes, bool,
96: private_prf_plus_t *this, size_t length, uint8_t *buffer)
97: {
98: size_t round, written = 0;
99:
100: while (length > 0)
101: {
102: if (this->buffer.len == this->used)
103: { /* buffer used, get next round */
104: if (!this->prf->get_bytes(this->prf, this->buffer, NULL))
105: {
106: return FALSE;
107: }
108: if (!this->apply_prf(this))
109: {
110: return FALSE;
111: }
112: this->used = 0;
113: }
114: round = min(length, this->buffer.len - this->used);
115: memcpy(buffer + written, this->buffer.ptr + this->used, round);
116:
117: length -= round;
118: this->used += round;
119: written += round;
120: }
121: return TRUE;
122: }
123:
124: METHOD(prf_plus_t, allocate_bytes, bool,
125: private_prf_plus_t *this, size_t length, chunk_t *chunk)
126: {
127: *chunk = chunk_alloc(length);
128: if (!get_bytes(this, length, chunk->ptr))
129: {
130: chunk_free(chunk);
131: return FALSE;
132: }
133: return TRUE;
134: }
135:
136: METHOD(prf_plus_t, destroy, void,
137: private_prf_plus_t *this)
138: {
139: chunk_clear(&this->buffer);
140: chunk_clear(&this->seed);
141: free(this);
142: }
143:
144: /*
145: * Description in header.
146: */
147: prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed)
148: {
149: private_prf_plus_t *this;
150:
151: INIT(this,
152: .public = {
153: .get_bytes = _get_bytes,
154: .allocate_bytes = _allocate_bytes,
155: .destroy = _destroy,
156: },
157: .prf = prf,
158: .seed = chunk_clone(seed),
159: .buffer = chunk_alloc(prf->get_block_size(prf)),
160: .apply_prf = counter ? apply_prf_counter : apply_prf,
161: .counter = 0x01,
162: );
163:
164: if (!this->apply_prf(this))
165: {
166: destroy(this);
167: return NULL;
168: }
169: return &this->public;
170: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>