blob: ee3cd45ac7f83244704d4867ccbde2cb4bb49d59 [file] [log] [blame]
Paul Bakker8123e9d2011-01-06 15:37:30 +00001/**
2 * \file cipher.c
3 *
4 * \brief Generic cipher wrapper for PolarSSL
5 *
6 * \author Adriaan de Jong <dejong@fox-it.com>
7 *
8 * Copyright (C) 2006-2010, Brainspark B.V.
9 *
10 * This file is part of PolarSSL (http://www.polarssl.org)
11 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
12 *
13 * All rights reserved.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 */
29
30#include "polarssl/config.h"
31
32#if defined(POLARSSL_CIPHER_C)
33
34#include "polarssl/cipher.h"
35#include "polarssl/cipher_wrap.h"
36
37#include <string.h>
38#include <stdlib.h>
39
Paul Bakkeraf5c85f2011-04-18 03:47:52 +000040#if defined _MSC_VER && !defined strcasecmp
41#define strcasecmp _stricmp
42#endif
43
Paul Bakker72f62662011-01-16 21:27:44 +000044static const int supported_ciphers[] = {
45
46#if defined(POLARSSL_AES_C)
47 POLARSSL_CIPHER_AES_128_CBC,
48 POLARSSL_CIPHER_AES_192_CBC,
49 POLARSSL_CIPHER_AES_256_CBC,
50#endif /* defined(POLARSSL_AES_C) */
51
52#if defined(POLARSSL_CAMELLIA_C)
53 POLARSSL_CIPHER_CAMELLIA_128_CBC,
54 POLARSSL_CIPHER_CAMELLIA_192_CBC,
55 POLARSSL_CIPHER_CAMELLIA_256_CBC,
56#endif /* defined(POLARSSL_CAMELLIA_C) */
57
58#if defined(POLARSSL_DES_C)
59 POLARSSL_CIPHER_DES_CBC,
60 POLARSSL_CIPHER_DES_EDE_CBC,
61 POLARSSL_CIPHER_DES_EDE3_CBC,
62#endif /* defined(POLARSSL_DES_C) */
63
64 0
65};
66
67const int *cipher_list( void )
68{
69 return supported_ciphers;
70}
71
Paul Bakker8123e9d2011-01-06 15:37:30 +000072const cipher_info_t *cipher_info_from_type( cipher_type_t cipher_type )
73{
74 /* Find static cipher information */
75 switch ( cipher_type )
76 {
77#if defined(POLARSSL_AES_C)
78 case POLARSSL_CIPHER_AES_128_CBC:
79 return &aes_128_cbc_info;
80 case POLARSSL_CIPHER_AES_192_CBC:
81 return &aes_192_cbc_info;
82 case POLARSSL_CIPHER_AES_256_CBC:
83 return &aes_256_cbc_info;
84#endif
85
86#if defined(POLARSSL_CAMELLIA_C)
87 case POLARSSL_CIPHER_CAMELLIA_128_CBC:
88 return &camellia_128_cbc_info;
89 case POLARSSL_CIPHER_CAMELLIA_192_CBC:
90 return &camellia_192_cbc_info;
91 case POLARSSL_CIPHER_CAMELLIA_256_CBC:
92 return &camellia_256_cbc_info;
93#endif
94
95#if defined(POLARSSL_DES_C)
96 case POLARSSL_CIPHER_DES_CBC:
97 return &des_cbc_info;
98 case POLARSSL_CIPHER_DES_EDE_CBC:
99 return &des_ede_cbc_info;
100 case POLARSSL_CIPHER_DES_EDE3_CBC:
101 return &des_ede3_cbc_info;
102#endif
103
104 default:
105 return NULL;
106 }
107}
108
109const cipher_info_t *cipher_info_from_string( const char *cipher_name )
110{
111 if( NULL == cipher_name )
112 return NULL;
113
114 /* Get the appropriate digest information */
115#if defined(POLARSSL_CAMELLIA_C)
116 if( !strcasecmp( "CAMELLIA-128-CBC", cipher_name ) )
117 return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CBC );
118 if( !strcasecmp( "CAMELLIA-192-CBC", cipher_name ) )
119 return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CBC );
120 if( !strcasecmp( "CAMELLIA-256-CBC", cipher_name ) )
121 return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CBC );
122#endif
123#if defined(POLARSSL_AES_C)
124 if( !strcasecmp( "AES-128-CBC", cipher_name ) )
125 return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CBC );
126 if( !strcasecmp( "AES-192-CBC", cipher_name ) )
127 return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CBC );
128 if( !strcasecmp( "AES-256-CBC", cipher_name ) )
129 return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CBC );
130#endif
131#if defined(POLARSSL_DES_C)
132 if( !strcasecmp( "DES-CBC", cipher_name ) )
133 return cipher_info_from_type( POLARSSL_CIPHER_DES_CBC );
134 if( !strcasecmp( "DES-EDE-CBC", cipher_name ) )
135 return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE_CBC );
136 if( !strcasecmp( "DES-EDE3-CBC", cipher_name ) )
137 return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE3_CBC );
138#endif
139 return NULL;
140}
141
142int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info )
143{
144 if( NULL == cipher_info || NULL == ctx )
145 return 1;
146
147 memset( ctx, 0, sizeof( ctx ) );
148
149 if( NULL == ( ctx->cipher_ctx = cipher_info->ctx_alloc_func() ) )
150 return 2;
151
152 ctx->cipher_info = cipher_info;
153
154 return 0;
155}
156
157int cipher_free_ctx( cipher_context_t *ctx )
158{
159 if( ctx == NULL || ctx->cipher_info == NULL )
160 return 1;
161
162 ctx->cipher_info->ctx_free_func( ctx->cipher_ctx );
163
164 return 0;
165}
166
167int cipher_setkey( cipher_context_t *ctx, const unsigned char *key,
168 int key_length, const operation_t operation )
169{
170 if( NULL == ctx || NULL == ctx->cipher_info )
171 return 1;
172
173 ctx->key_length = key_length;
174 ctx->operation = operation;
175
176 if (POLARSSL_ENCRYPT == operation)
177 return ctx->cipher_info->setkey_enc_func( ctx->cipher_ctx, key,
178 ctx->key_length );
179
180 if (POLARSSL_DECRYPT == operation)
181 return ctx->cipher_info->setkey_dec_func( ctx->cipher_ctx, key,
182 ctx->key_length );
183
184 return 1;
185}
186
187int cipher_reset( cipher_context_t *ctx, const unsigned char *iv )
188{
189 if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
190 return 1;
191
192 ctx->unprocessed_len = 0;
193
194 memcpy( ctx->iv, iv, cipher_get_iv_size( ctx ) );
195
196 return 0;
197}
198
199int cipher_update( cipher_context_t *ctx, const unsigned char *input, int ilen,
200 unsigned char *output, int *olen )
201{
202 int copy_len = 0;
203
Paul Bakkera885d682011-01-20 16:35:05 +0000204 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ||
205 input == output )
206 {
Paul Bakker8123e9d2011-01-06 15:37:30 +0000207 return 1;
Paul Bakkera885d682011-01-20 16:35:05 +0000208 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000209
210 *olen = 0;
211
212 if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
213 {
214 /*
215 * If there is not enough data for a full block, cache it.
216 */
217 if( ( ctx->operation == POLARSSL_DECRYPT &&
218 ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) ||
219 ( ctx->operation == POLARSSL_ENCRYPT &&
220 ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) )
221 {
222 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
223 ilen );
224
225 ctx->unprocessed_len += ilen;
226 return 0;
227 }
228
229 /*
230 * Process cached data first
231 */
232 if( ctx->unprocessed_len != 0 )
233 {
234 copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len;
235
236 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
237 copy_len );
238
239 if( 0 != ctx->cipher_info->cbc_func( ctx->cipher_ctx,
240 ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
241 ctx->unprocessed_data, output) )
242 {
243 return 1;
244 }
245
246 *olen += cipher_get_block_size( ctx );
247 output += cipher_get_block_size( ctx );
248 ctx->unprocessed_len = 0;
249
250 input += copy_len;
251 ilen -= copy_len;
252 }
253
254 /*
255 * Cache final, incomplete block
256 */
257 if( 0 != ilen )
258 {
259 copy_len = ilen % cipher_get_block_size( ctx );
260 if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT )
261 copy_len = cipher_get_block_size(ctx);
262
263 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
264 copy_len );
265
266 ctx->unprocessed_len += copy_len;
267 ilen -= copy_len;
268 }
269
270 /*
271 * Process remaining full blocks
272 */
273 if( ilen )
274 {
275 if( 0 != ctx->cipher_info->cbc_func( ctx->cipher_ctx,
276 ctx->operation, ilen, ctx->iv, input, output ) )
277 {
278 return 1;
279 }
280 *olen += ilen;
281 }
282
283 return 0;
284 }
285
286 return 1;
287}
288
289static void add_pkcs_padding( unsigned char *output, unsigned char output_len,
290 int data_len )
291{
292 unsigned char padding_len = output_len - data_len;
293 unsigned char i = 0;
294
295 for( i = 0; i < padding_len; i++ )
296 output[data_len + i] = padding_len;
297}
298
299static int get_pkcs_padding( unsigned char *input, unsigned char input_len,
300 int *data_len)
301{
302 int i = 0;
303 unsigned char padding_len = 0;
304
Paul Bakkera885d682011-01-20 16:35:05 +0000305 if( NULL == input || NULL == data_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000306 return 1;
307
308 padding_len = input[input_len - 1];
309
Paul Bakkera885d682011-01-20 16:35:05 +0000310 if( padding_len > input_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000311 return 2;
312
Paul Bakkera885d682011-01-20 16:35:05 +0000313 for( i = input_len - padding_len; i < input_len; i++ )
314 if( input[i] != padding_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000315 return 2;
316
317 *data_len = input_len - padding_len;
318
319 return 0;
320}
321
322int cipher_finish( cipher_context_t *ctx, unsigned char *output, int *olen)
323{
324 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
325 return 1;
326
327 *olen = 0;
328
329 if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )
330 {
331 if( POLARSSL_ENCRYPT == ctx->operation )
332 {
333 add_pkcs_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ),
334 ctx->unprocessed_len );
335 }
336 else if ( cipher_get_block_size( ctx ) != ctx->unprocessed_len )
337 {
338 /* For decrypt operations, expect a full block */
339 return 1;
340 }
341
342 /* cipher block */
343 if( 0 != ctx->cipher_info->cbc_func( ctx->cipher_ctx, ctx->operation,
344 cipher_get_block_size( ctx ), ctx->iv, ctx->unprocessed_data,
345 output ) )
346 {
347 return 1;
348 }
349
350 /* Set output size for decryption */
351 if( POLARSSL_DECRYPT == ctx->operation )
352 return get_pkcs_padding( output, cipher_get_block_size( ctx ), olen );
353
354 /* Set output size for encryption */
355 *olen = cipher_get_block_size( ctx );
356 return 0;
357 }
358
359 return 1;
360}
361
362#if defined(POLARSSL_SELF_TEST)
363
364#include <stdio.h>
365
366#define ASSERT(x) if (!(x)) { \
367 printf( "failed with %i at %s\n", value, (#x) ); \
368 return( 1 ); \
369}
370/*
371 * Checkup routine
372 */
373
374int cipher_self_test( int verbose )
375{
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000376 ((void) verbose);
377
Paul Bakker8123e9d2011-01-06 15:37:30 +0000378 return( 0 );
379}
380
381#endif
382
383#endif