Annotation of embedaddon/strongswan/src/libstrongswan/plugins/ctr/ctr_ipsec_crypter.c, revision 1.1.1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>