2 * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
3 * Copyright (C) 2005-2006 Martin Willi
4 * Copyright (C) 2009 Andreas Steffen
5 * Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "serpent_crypter.h"
21 #define SERPENT_BLOCK_SIZE 16
23 typedef struct private_serpent_crypter_t private_serpent_crypter_t
;
26 * Class implementing the AES symmetric encryption algorithm.
30 struct private_serpent_crypter_t
{
33 * Public part of this class.
35 serpent_crypter_t
public;
40 serpent_context serpent_ctx
;
43 * Key size of this Serpent cipher object.
49 * Implementation of crypter_t.encrypt.
51 static void encrypt(private_serpent_crypter_t
*this, chunk_t data
, chunk_t iv
,
59 *encrypted
= chunk_alloc(data
.len
);
68 while ( pos
< data
.len
)
70 const u_int32_t
*iv_i
;
72 iv_i
= (pos
) ?
(const u_int32_t
*)(out
- 16) :
73 (const u_int32_t
*)(iv
.ptr
);
74 *((u_int32_t
*)(&out
[ 0])) = iv_i
[0] ^ *((const u_int32_t
*)(&in
[ 0]));
75 *((u_int32_t
*)(&out
[ 4])) = iv_i
[1] ^ *((const u_int32_t
*)(&in
[ 4]));
76 *((u_int32_t
*)(&out
[ 8])) = iv_i
[2] ^ *((const u_int32_t
*)(&in
[ 8]));
77 *((u_int32_t
*)(&out
[12])) = iv_i
[3] ^ *((const u_int32_t
*)(&in
[12]));
79 serpent_encrypt(&this->serpent_ctx
, out
, out
);
81 in
+= SERPENT_BLOCK_SIZE
;
82 out
+= SERPENT_BLOCK_SIZE
;
83 pos
+= SERPENT_BLOCK_SIZE
;
88 * Implementation of crypter_t.decrypt.
90 static void decrypt(private_serpent_crypter_t
*this, chunk_t data
, chunk_t iv
,
93 int pos
= data
.len
- SERPENT_BLOCK_SIZE
;
98 *decrypted
= chunk_alloc(data
.len
);
111 const u_int32_t
*iv_i
;
113 serpent_decrypt(&this->serpent_ctx
, in
, out
);
115 iv_i
= (pos
) ?
(const u_int32_t
*)(in
- 16) :
116 (const u_int32_t
*)(iv
.ptr
);
117 *((u_int32_t
*)(&out
[ 0])) ^= iv_i
[0];
118 *((u_int32_t
*)(&out
[ 4])) ^= iv_i
[1];
119 *((u_int32_t
*)(&out
[ 8])) ^= iv_i
[2];
120 *((u_int32_t
*)(&out
[12])) ^= iv_i
[3];
122 in
-= SERPENT_BLOCK_SIZE
;
123 out
-= SERPENT_BLOCK_SIZE
;
124 pos
-= SERPENT_BLOCK_SIZE
;
129 * Implementation of crypter_t.get_block_size.
131 static size_t get_block_size (private_serpent_crypter_t
*this)
133 return SERPENT_BLOCK_SIZE
;
137 * Implementation of crypter_t.get_key_size.
139 static size_t get_key_size (private_serpent_crypter_t
*this)
141 return this->key_size
;
145 * Implementation of crypter_t.set_key.
147 static void set_key (private_serpent_crypter_t
*this, chunk_t key
)
149 serpent_set_key(&this->serpent_ctx
, key
.ptr
, key
.len
);
153 * Implementation of crypter_t.destroy and serpent_crypter_t.destroy.
155 static void destroy (private_serpent_crypter_t
*this)
161 * Described in header
163 serpent_crypter_t
*serpent_crypter_create(encryption_algorithm_t algo
, size_t key_size
)
165 private_serpent_crypter_t
*this;
167 if (algo
!= ENCR_SERPENT_CBC
|| !(key_size
== 16 || key_size
== 32))
172 this = malloc_thing(private_serpent_crypter_t
);
174 this->public.crypter_interface
.encrypt
= (void (*) (crypter_t
*, chunk_t
,chunk_t
, chunk_t
*)) encrypt
;
175 this->public.crypter_interface
.decrypt
= (void (*) (crypter_t
*, chunk_t
, chunk_t
, chunk_t
*)) decrypt
;
176 this->public.crypter_interface
.get_block_size
= (size_t (*) (crypter_t
*)) get_block_size
;
177 this->public.crypter_interface
.get_key_size
= (size_t (*) (crypter_t
*)) get_key_size
;
178 this->public.crypter_interface
.set_key
= (void (*) (crypter_t
*,chunk_t
)) set_key
;
179 this->public.crypter_interface
.destroy
= (void (*) (crypter_t
*)) destroy
;
181 return &(this->public);