File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / crypto / iv / iv_gen_seq.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:  * 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 "iv_gen_seq.h"
   17: 
   18: /**
   19:  * Magic value for the initial IV state
   20:  */
   21: #define SEQ_IV_INIT_STATE (~(uint64_t)0)
   22: #define SEQ_IV_HIGH_MASK (1ULL << 63)
   23: 
   24: typedef struct private_iv_gen_t private_iv_gen_t;
   25: 
   26: /**
   27:  * Private data of an iv_gen_t object.
   28:  */
   29: struct private_iv_gen_t {
   30: 
   31: 	/**
   32: 	 * Public iv_gen_t interface.
   33: 	 */
   34: 	iv_gen_t public;
   35: 
   36: 	/**
   37: 	 * Previously passed sequence number in lower space to enforce uniqueness
   38: 	 */
   39: 	uint64_t prevl;
   40: 
   41: 	/**
   42: 	 * Previously passed sequence number in upper space to enforce uniqueness
   43: 	 */
   44: 	uint64_t prevh;
   45: 
   46: 	/**
   47: 	 * Salt to mask counter
   48: 	 */
   49: 	uint8_t *salt;
   50: };
   51: 
   52: METHOD(iv_gen_t, get_iv, bool,
   53: 	private_iv_gen_t *this, uint64_t seq, size_t size, uint8_t *buffer)
   54: {
   55: 	uint8_t iv[sizeof(uint64_t)];
   56: 	size_t len = size;
   57: 
   58: 	if (!this->salt)
   59: 	{
   60: 		return FALSE;
   61: 	}
   62: 	if (size < sizeof(uint64_t))
   63: 	{
   64: 		return FALSE;
   65: 	}
   66: 	if (this->prevl != SEQ_IV_INIT_STATE && seq <= this->prevl)
   67: 	{
   68: 		seq |= SEQ_IV_HIGH_MASK;
   69: 		if (this->prevh != SEQ_IV_INIT_STATE && seq <= this->prevh)
   70: 		{
   71: 			return FALSE;
   72: 		}
   73: 	}
   74: 	if ((seq | SEQ_IV_HIGH_MASK) == SEQ_IV_INIT_STATE)
   75: 	{
   76: 		return FALSE;
   77: 	}
   78: 	if (seq & SEQ_IV_HIGH_MASK)
   79: 	{
   80: 		this->prevh = seq;
   81: 	}
   82: 	else
   83: 	{
   84: 		this->prevl = seq;
   85: 	}
   86: 	if (len > sizeof(uint64_t))
   87: 	{
   88: 		len = sizeof(uint64_t);
   89: 		memset(buffer, 0, size - len);
   90: 	}
   91: 	htoun64(iv, seq);
   92: 	memxor(iv, this->salt, sizeof(uint64_t));
   93: 	memcpy(buffer + size - len, iv + sizeof(uint64_t) - len, len);
   94: 	return TRUE;
   95: }
   96: 
   97: METHOD(iv_gen_t, allocate_iv, bool,
   98: 	private_iv_gen_t *this, uint64_t seq, size_t size, chunk_t *chunk)
   99: {
  100: 	*chunk = chunk_alloc(size);
  101: 	if (!get_iv(this, seq, chunk->len, chunk->ptr))
  102: 	{
  103: 		chunk_free(chunk);
  104: 		return FALSE;
  105: 	}
  106: 	return TRUE;
  107: }
  108: 
  109: METHOD(iv_gen_t, destroy, void,
  110: 	private_iv_gen_t *this)
  111: {
  112: 	free(this->salt);
  113: 	free(this);
  114: }
  115: 
  116: iv_gen_t *iv_gen_seq_create()
  117: {
  118: 	private_iv_gen_t *this;
  119: 	rng_t *rng;
  120: 
  121: 	INIT(this,
  122: 		.public = {
  123: 			.get_iv = _get_iv,
  124: 			.allocate_iv = _allocate_iv,
  125: 			.destroy = _destroy,
  126: 		},
  127: 		.prevl = SEQ_IV_INIT_STATE,
  128: 		.prevh = SEQ_IV_INIT_STATE,
  129: 	);
  130: 
  131: 	rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
  132: 	if (rng)
  133: 	{
  134: 		this->salt = malloc(sizeof(uint64_t));
  135: 		if (!rng->get_bytes(rng, sizeof(uint64_t), this->salt))
  136: 		{
  137: 			free(this->salt);
  138: 			this->salt = NULL;
  139: 		}
  140: 		rng->destroy(rng);
  141: 	}
  142: 
  143: 	return &this->public;
  144: }

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