Return to ctr_ipsec_crypter.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / ctr |
1.1 misho 1: /* 2: * Copyright (C) 2010 Martin Willi 3: * Copyright (C) 2010 revosec AG 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 "ctr_ipsec_crypter.h" 17: 18: typedef struct private_ctr_ipsec_crypter_t private_ctr_ipsec_crypter_t; 19: 20: /** 21: * Private data of an ctr_ipsec_crypter_t object. 22: */ 23: struct private_ctr_ipsec_crypter_t { 24: 25: /** 26: * Public ctr_ipsec_crypter_t interface. 27: */ 28: ctr_ipsec_crypter_t public; 29: 30: /** 31: * Underlying CBC crypter 32: */ 33: crypter_t *crypter; 34: 35: /** 36: * counter state 37: */ 38: struct { 39: char nonce[4]; 40: char iv[8]; 41: uint32_t counter; 42: } __attribute__((packed)) state; 43: }; 44: 45: /** 46: * Do the CTR crypto operation 47: */ 48: static bool crypt_ctr(private_ctr_ipsec_crypter_t *this, 49: chunk_t in, chunk_t out) 50: { 51: size_t is, bs; 52: chunk_t state; 53: 54: is = this->crypter->get_iv_size(this->crypter); 55: bs = sizeof(this->state); 56: 57: this->state.counter = htonl(1); 58: state = chunk_create((char*)&this->state, bs); 59: 60: while (in.len > 0) 61: { 62: char iv[is], block[bs]; 63: 64: memset(iv, 0, is); 65: memcpy(block, state.ptr, bs); 66: if (!this->crypter->encrypt(this->crypter, chunk_create(block, bs), 67: chunk_create(iv, is), NULL)) 68: { 69: return FALSE; 70: } 71: chunk_increment(state); 72: 73: if (in.ptr != out.ptr) 74: { 75: memcpy(out.ptr, in.ptr, min(in.len, bs)); 76: } 77: memxor(out.ptr, block, min(in.len, bs)); 78: in = chunk_skip(in, bs); 79: out = chunk_skip(out, bs); 80: } 81: return TRUE; 82: } 83: 84: METHOD(crypter_t, crypt, bool, 85: private_ctr_ipsec_crypter_t *this, chunk_t in, chunk_t iv, chunk_t *out) 86: { 87: memcpy(this->state.iv, iv.ptr, sizeof(this->state.iv)); 88: 89: if (out) 90: { 91: *out = chunk_alloc(in.len); 92: return crypt_ctr(this, in, *out); 93: } 94: return crypt_ctr(this, in, in); 95: } 96: 97: METHOD(crypter_t, get_block_size, size_t, 98: private_ctr_ipsec_crypter_t *this) 99: { 100: return 1; 101: } 102: 103: METHOD(crypter_t, get_iv_size, size_t, 104: private_ctr_ipsec_crypter_t *this) 105: { 106: return sizeof(this->state.iv); 107: } 108: 109: METHOD(crypter_t, get_key_size, size_t, 110: private_ctr_ipsec_crypter_t *this) 111: { 112: return this->crypter->get_key_size(this->crypter) 113: + sizeof(this->state.nonce); 114: } 115: 116: METHOD(crypter_t, set_key, bool, 117: private_ctr_ipsec_crypter_t *this, chunk_t key) 118: { 119: memcpy(this->state.nonce, key.ptr + key.len - sizeof(this->state.nonce), 120: sizeof(this->state.nonce)); 121: key.len -= sizeof(this->state.nonce); 122: return this->crypter->set_key(this->crypter, key); 123: } 124: 125: METHOD(crypter_t, destroy, void, 126: private_ctr_ipsec_crypter_t *this) 127: { 128: this->crypter->destroy(this->crypter); 129: free(this); 130: } 131: 132: /** 133: * See header 134: */ 135: ctr_ipsec_crypter_t *ctr_ipsec_crypter_create(encryption_algorithm_t algo, 136: size_t key_size) 137: { 138: private_ctr_ipsec_crypter_t *this; 139: 140: switch (algo) 141: { 142: case ENCR_AES_CTR: 143: algo = ENCR_AES_CBC; 144: break; 145: case ENCR_CAMELLIA_CTR: 146: algo = ENCR_CAMELLIA_CBC; 147: break; 148: default: 149: return NULL; 150: } 151: 152: INIT(this, 153: .public = { 154: .crypter = { 155: .encrypt = _crypt, 156: .decrypt = _crypt, 157: .get_block_size = _get_block_size, 158: .get_iv_size = _get_iv_size, 159: .get_key_size = _get_key_size, 160: .set_key = _set_key, 161: .destroy = _destroy, 162: }, 163: }, 164: .crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size), 165: ); 166: 167: if (!this->crypter) 168: { 169: free(this); 170: return NULL; 171: } 172: 173: return &this->public; 174: }