Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_xof.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2020 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
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 <openssl/evp.h>
17:
18: /* SHA3 was added with 1.1.1 */
19: #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHAKE)
20:
21: #include "openssl_xof.h"
22:
23: #define KECCAK_STATE_SIZE 200 /* 1600 bits*/
24:
25: typedef struct private_xof_t private_xof_t;
26:
27: /**
28: * Private data
29: */
30: struct private_xof_t {
31:
32: /**
33: * Public interface.
34: */
35: xof_t public;
36:
37: /**
38: * XOF algorithm to be used
39: */
40: ext_out_function_t algorithm;
41:
42: /**
43: * Internal type reference
44: */
45: const EVP_MD *md;
46:
47: /**
48: * Internal context
49: */
50: EVP_MD_CTX *ctx;
51:
52: /**
53: * Current seed
54: */
55: chunk_t seed;
56:
57: /**
58: * Offset into generated data
59: */
60: size_t offset;
61: };
62:
63: METHOD(xof_t, get_type, ext_out_function_t,
64: private_xof_t *this)
65: {
66: return this->algorithm;
67: }
68:
69: METHOD(xof_t, get_bytes, bool,
70: private_xof_t *this, size_t out_len, uint8_t *buffer)
71: {
72: bool success = FALSE;
73: chunk_t data;
74:
75: /* we can call EVP_DigestFinalXOF() only once, so to support an arbitrary
76: * number of calls to get_bytes(), we request all the data we already
77: * requested previously and just ignore what we already handed out */
78: if (EVP_DigestInit_ex(this->ctx, this->md, NULL) == 1 &&
79: EVP_DigestUpdate(this->ctx, this->seed.ptr, this->seed.len) == 1)
80: {
81: data = chunk_alloc(out_len + this->offset);
82: if (EVP_DigestFinalXOF(this->ctx, data.ptr, data.len) == 1)
83: {
84: memcpy(buffer, data.ptr + this->offset, out_len);
85: this->offset += out_len;
86: success = TRUE;
87: }
88: chunk_clear(&data);
89: }
90: return success;
91: }
92:
93: METHOD(xof_t, allocate_bytes, bool,
94: private_xof_t *this, size_t out_len, chunk_t *chunk)
95: {
96: *chunk = chunk_alloc(out_len);
97: return get_bytes(this, out_len, chunk->ptr);
98: }
99:
100: METHOD(xof_t, get_block_size, size_t,
101: private_xof_t *this)
102: {
103: return EVP_MD_block_size(this->md);
104: }
105:
106: METHOD(xof_t, get_seed_size, size_t,
107: private_xof_t *this)
108: {
109: return KECCAK_STATE_SIZE - EVP_MD_block_size(this->md);
110: }
111:
112: METHOD(xof_t, set_seed, bool,
113: private_xof_t *this, chunk_t seed)
114: {
115: chunk_clear(&this->seed);
116: this->seed = chunk_clone(seed);
117: this->offset = 0;
118: return TRUE;
119: }
120:
121: METHOD(xof_t, destroy, void,
122: private_xof_t *this)
123: {
124: EVP_MD_CTX_free(this->ctx);
125: chunk_clear(&this->seed);
126: free(this);
127: }
128:
129: /*
130: * Described in header
131: */
132: xof_t *openssl_xof_create(ext_out_function_t algorithm)
133: {
134: private_xof_t *this;
135: const EVP_MD *md;
136:
137: switch (algorithm)
138: {
139: case XOF_SHAKE_128:
140: md = EVP_shake128();
141: break;
142: case XOF_SHAKE_256:
143: md = EVP_shake256();
144: break;
145: default:
146: return NULL;
147: }
148:
149: INIT(this,
150: .public = {
151: .get_type = _get_type,
152: .get_bytes = _get_bytes,
153: .allocate_bytes = _allocate_bytes,
154: .get_block_size = _get_block_size,
155: .get_seed_size = _get_seed_size,
156: .set_seed = _set_seed,
157: .destroy = _destroy,
158: },
159: .algorithm = algorithm,
160: .md = md,
161: .ctx = EVP_MD_CTX_new(),
162: );
163: return &this->public;
164: }
165:
166: #endif /* OPENSSL_NO_ECDH */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>