File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / crypto / aead.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 3 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2013 Tobias Brunner
    3:  * HSR Hochschule fuer Technik Rapperswil
    4:  *
    5:  * Copyright (C) 2010 Martin Willi
    6:  * Copyright (C) 2010 revosec AG
    7:  *
    8:  * This program is free software; you can redistribute it and/or modify it
    9:  * under the terms of the GNU General Public License as published by the
   10:  * Free Software Foundation; either version 2 of the License, or (at your
   11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
   12:  *
   13:  * This program is distributed in the hope that it will be useful, but
   14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16:  * for more details.
   17:  */
   18: 
   19: #include "aead.h"
   20: 
   21: #include <utils/debug.h>
   22: #include <crypto/iv/iv_gen_rand.h>
   23: 
   24: typedef struct private_aead_t private_aead_t;
   25: 
   26: /**
   27:  * Private data of an aead_t object.
   28:  */
   29: struct private_aead_t {
   30: 
   31: 	/**
   32: 	 * Public aead_t interface.
   33: 	 */
   34: 	aead_t public;
   35: 
   36: 	/**
   37: 	 * traditional crypter
   38: 	 */
   39: 	crypter_t *crypter;
   40: 
   41: 	/**
   42: 	 * traditional signer
   43: 	 */
   44: 	signer_t *signer;
   45: 
   46: 	/**
   47: 	 * IV generator
   48: 	 */
   49: 	iv_gen_t *iv_gen;
   50: };
   51: 
   52: METHOD(aead_t, encrypt, bool,
   53: 	private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
   54: 	chunk_t *encrypted)
   55: {
   56: 	chunk_t encr, sig;
   57: 
   58: 	if (!this->signer->get_signature(this->signer, assoc, NULL) ||
   59: 		!this->signer->get_signature(this->signer, iv, NULL))
   60: 	{
   61: 		return FALSE;
   62: 	}
   63: 
   64: 	if (encrypted)
   65: 	{
   66: 		if (!this->crypter->encrypt(this->crypter, plain, iv, &encr))
   67: 		{
   68: 			return FALSE;
   69: 		}
   70: 		if (!this->signer->allocate_signature(this->signer, encr, &sig))
   71: 		{
   72: 			free(encr.ptr);
   73: 			return FALSE;
   74: 		}
   75: 		*encrypted = chunk_cat("cmm", iv, encr, sig);
   76: 	}
   77: 	else
   78: 	{
   79: 		if (!this->crypter->encrypt(this->crypter, plain, iv, NULL) ||
   80: 			!this->signer->get_signature(this->signer,
   81: 										 plain, plain.ptr + plain.len))
   82: 		{
   83: 			return FALSE;
   84: 		}
   85: 	}
   86: 	return TRUE;
   87: }
   88: 
   89: METHOD(aead_t, decrypt, bool,
   90: 	private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
   91: 	chunk_t *plain)
   92: {
   93: 	chunk_t sig;
   94: 	size_t bs;
   95: 
   96: 	bs = this->crypter->get_block_size(this->crypter);
   97: 	sig.len = this->signer->get_block_size(this->signer);
   98: 	if (sig.len > encrypted.len || (encrypted.len - sig.len) % bs)
   99: 	{
  100: 		DBG1(DBG_LIB, "invalid encrypted data length %d with block size %d",
  101: 			encrypted.len - sig.len, bs);
  102: 		return FALSE;
  103: 	}
  104: 	chunk_split(encrypted, "mm", encrypted.len - sig.len,
  105: 				&encrypted, sig.len, &sig);
  106: 
  107: 	if (!this->signer->get_signature(this->signer, assoc, NULL) ||
  108: 		!this->signer->get_signature(this->signer, iv, NULL))
  109: 	{
  110: 		return FALSE;
  111: 	}
  112: 	if (!this->signer->verify_signature(this->signer, encrypted, sig))
  113: 	{
  114: 		DBG1(DBG_LIB, "MAC verification failed");
  115: 		return FALSE;
  116: 	}
  117: 	return this->crypter->decrypt(this->crypter, encrypted, iv, plain);
  118: }
  119: 
  120: METHOD(aead_t, get_block_size, size_t,
  121: 	private_aead_t *this)
  122: {
  123: 	return this->crypter->get_block_size(this->crypter);
  124: }
  125: 
  126: METHOD(aead_t, get_icv_size, size_t,
  127: 	private_aead_t *this)
  128: {
  129: 	return this->signer->get_block_size(this->signer);
  130: }
  131: 
  132: METHOD(aead_t, get_iv_size, size_t,
  133: 	private_aead_t *this)
  134: {
  135: 	return this->crypter->get_iv_size(this->crypter);
  136: }
  137: 
  138: METHOD(aead_t, get_iv_gen, iv_gen_t*,
  139: 	private_aead_t *this)
  140: {
  141: 	return this->iv_gen;
  142: }
  143: 
  144: METHOD(aead_t, get_key_size, size_t,
  145: 	private_aead_t *this)
  146: {
  147: 	return this->crypter->get_key_size(this->crypter) +
  148: 			this->signer->get_key_size(this->signer);
  149: }
  150: 
  151: METHOD(aead_t, set_key, bool,
  152: 	private_aead_t *this, chunk_t key)
  153: {
  154: 	chunk_t sig, enc;
  155: 
  156: 	chunk_split(key, "mm", this->signer->get_key_size(this->signer), &sig,
  157: 				this->crypter->get_key_size(this->crypter), &enc);
  158: 
  159: 	return this->signer->set_key(this->signer, sig) &&
  160: 		   this->crypter->set_key(this->crypter, enc);
  161: }
  162: 
  163: METHOD(aead_t, destroy, void,
  164: 	private_aead_t *this)
  165: {
  166: 	this->iv_gen->destroy(this->iv_gen);
  167: 	this->crypter->destroy(this->crypter);
  168: 	this->signer->destroy(this->signer);
  169: 	free(this);
  170: }
  171: 
  172: /**
  173:  * See header
  174:  */
  175: aead_t *aead_create(crypter_t *crypter, signer_t *signer, iv_gen_t *iv_gen)
  176: {
  177: 	private_aead_t *this;
  178: 
  179: 	INIT(this,
  180: 		.public = {
  181: 			.encrypt = _encrypt,
  182: 			.decrypt = _decrypt,
  183: 			.get_block_size = _get_block_size,
  184: 			.get_icv_size = _get_icv_size,
  185: 			.get_iv_size = _get_iv_size,
  186: 			.get_iv_gen = _get_iv_gen,
  187: 			.get_key_size = _get_key_size,
  188: 			.set_key = _set_key,
  189: 			.destroy = _destroy,
  190: 		},
  191: 		.crypter = crypter,
  192: 		.signer = signer,
  193: 		.iv_gen = iv_gen,
  194: 	);
  195: 
  196: 	return &this->public;
  197: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>