Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_xof.c, revision 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>