blob: 56ac7c44ffa11c61c517f13c4e4340041e6c9abf [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
Paul Bakker8123e9d2011-01-06 15:37:30 +000037#include <stdlib.h>
38
Paul Bakkeraf5c85f2011-04-18 03:47:52 +000039#if defined _MSC_VER && !defined strcasecmp
40#define strcasecmp _stricmp
41#endif
42
Paul Bakker72f62662011-01-16 21:27:44 +000043static const int supported_ciphers[] = {
44
45#if defined(POLARSSL_AES_C)
46 POLARSSL_CIPHER_AES_128_CBC,
47 POLARSSL_CIPHER_AES_192_CBC,
48 POLARSSL_CIPHER_AES_256_CBC,
49#endif /* defined(POLARSSL_AES_C) */
50
51#if defined(POLARSSL_CAMELLIA_C)
52 POLARSSL_CIPHER_CAMELLIA_128_CBC,
53 POLARSSL_CIPHER_CAMELLIA_192_CBC,
54 POLARSSL_CIPHER_CAMELLIA_256_CBC,
55#endif /* defined(POLARSSL_CAMELLIA_C) */
56
57#if defined(POLARSSL_DES_C)
58 POLARSSL_CIPHER_DES_CBC,
59 POLARSSL_CIPHER_DES_EDE_CBC,
60 POLARSSL_CIPHER_DES_EDE3_CBC,
61#endif /* defined(POLARSSL_DES_C) */
62
63 0
64};
65
66const int *cipher_list( void )
67{
68 return supported_ciphers;
69}
70
Paul Bakker8123e9d2011-01-06 15:37:30 +000071const cipher_info_t *cipher_info_from_type( cipher_type_t cipher_type )
72{
73 /* Find static cipher information */
74 switch ( cipher_type )
75 {
76#if defined(POLARSSL_AES_C)
77 case POLARSSL_CIPHER_AES_128_CBC:
78 return &aes_128_cbc_info;
79 case POLARSSL_CIPHER_AES_192_CBC:
80 return &aes_192_cbc_info;
81 case POLARSSL_CIPHER_AES_256_CBC:
82 return &aes_256_cbc_info;
83#endif
84
85#if defined(POLARSSL_CAMELLIA_C)
86 case POLARSSL_CIPHER_CAMELLIA_128_CBC:
87 return &camellia_128_cbc_info;
88 case POLARSSL_CIPHER_CAMELLIA_192_CBC:
89 return &camellia_192_cbc_info;
90 case POLARSSL_CIPHER_CAMELLIA_256_CBC:
91 return &camellia_256_cbc_info;
92#endif
93
94#if defined(POLARSSL_DES_C)
95 case POLARSSL_CIPHER_DES_CBC:
96 return &des_cbc_info;
97 case POLARSSL_CIPHER_DES_EDE_CBC:
98 return &des_ede_cbc_info;
99 case POLARSSL_CIPHER_DES_EDE3_CBC:
100 return &des_ede3_cbc_info;
101#endif
102
103 default:
104 return NULL;
105 }
106}
107
108const cipher_info_t *cipher_info_from_string( const char *cipher_name )
109{
110 if( NULL == cipher_name )
111 return NULL;
112
113 /* Get the appropriate digest information */
114#if defined(POLARSSL_CAMELLIA_C)
115 if( !strcasecmp( "CAMELLIA-128-CBC", cipher_name ) )
116 return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CBC );
117 if( !strcasecmp( "CAMELLIA-192-CBC", cipher_name ) )
118 return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CBC );
119 if( !strcasecmp( "CAMELLIA-256-CBC", cipher_name ) )
120 return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CBC );
121#endif
122#if defined(POLARSSL_AES_C)
123 if( !strcasecmp( "AES-128-CBC", cipher_name ) )
124 return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CBC );
125 if( !strcasecmp( "AES-192-CBC", cipher_name ) )
126 return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CBC );
127 if( !strcasecmp( "AES-256-CBC", cipher_name ) )
128 return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CBC );
129#endif
130#if defined(POLARSSL_DES_C)
131 if( !strcasecmp( "DES-CBC", cipher_name ) )
132 return cipher_info_from_type( POLARSSL_CIPHER_DES_CBC );
133 if( !strcasecmp( "DES-EDE-CBC", cipher_name ) )
134 return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE_CBC );
135 if( !strcasecmp( "DES-EDE3-CBC", cipher_name ) )
136 return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE3_CBC );
137#endif
138 return NULL;
139}
140
141int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info )
142{
143 if( NULL == cipher_info || NULL == ctx )
144 return 1;
145
146 memset( ctx, 0, sizeof( ctx ) );
147
148 if( NULL == ( ctx->cipher_ctx = cipher_info->ctx_alloc_func() ) )
149 return 2;
150
151 ctx->cipher_info = cipher_info;
152
153 return 0;
154}
155
156int cipher_free_ctx( cipher_context_t *ctx )
157{
158 if( ctx == NULL || ctx->cipher_info == NULL )
159 return 1;
160
161 ctx->cipher_info->ctx_free_func( ctx->cipher_ctx );
162
163 return 0;
164}
165
166int cipher_setkey( cipher_context_t *ctx, const unsigned char *key,
167 int key_length, const operation_t operation )
168{
169 if( NULL == ctx || NULL == ctx->cipher_info )
170 return 1;
171
172 ctx->key_length = key_length;
173 ctx->operation = operation;
174
175 if (POLARSSL_ENCRYPT == operation)
176 return ctx->cipher_info->setkey_enc_func( ctx->cipher_ctx, key,
177 ctx->key_length );
178
179 if (POLARSSL_DECRYPT == operation)
180 return ctx->cipher_info->setkey_dec_func( ctx->cipher_ctx, key,
181 ctx->key_length );
182
183 return 1;
184}
185
186int cipher_reset( cipher_context_t *ctx, const unsigned char *iv )
187{
188 if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
189 return 1;
190
191 ctx->unprocessed_len = 0;
192
193 memcpy( ctx->iv, iv, cipher_get_iv_size( ctx ) );
194
195 return 0;
196}
197
Paul Bakker23986e52011-04-24 08:57:21 +0000198int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen,
199 unsigned char *output, size_t *olen )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000200{
Paul Bakker23986e52011-04-24 08:57:21 +0000201 size_t copy_len = 0;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000202
Paul Bakkera885d682011-01-20 16:35:05 +0000203 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ||
204 input == output )
205 {
Paul Bakker8123e9d2011-01-06 15:37:30 +0000206 return 1;
Paul Bakkera885d682011-01-20 16:35:05 +0000207 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000208
209 *olen = 0;
210
211 if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
212 {
213 /*
214 * If there is not enough data for a full block, cache it.
215 */
216 if( ( ctx->operation == POLARSSL_DECRYPT &&
217 ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) ||
218 ( ctx->operation == POLARSSL_ENCRYPT &&
219 ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) )
220 {
221 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
222 ilen );
223
224 ctx->unprocessed_len += ilen;
225 return 0;
226 }
227
228 /*
229 * Process cached data first
230 */
231 if( ctx->unprocessed_len != 0 )
232 {
233 copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len;
234
235 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
236 copy_len );
237
238 if( 0 != ctx->cipher_info->cbc_func( ctx->cipher_ctx,
239 ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
240 ctx->unprocessed_data, output) )
241 {
242 return 1;
243 }
244
245 *olen += cipher_get_block_size( ctx );
246 output += cipher_get_block_size( ctx );
247 ctx->unprocessed_len = 0;
248
249 input += copy_len;
250 ilen -= copy_len;
251 }
252
253 /*
254 * Cache final, incomplete block
255 */
256 if( 0 != ilen )
257 {
258 copy_len = ilen % cipher_get_block_size( ctx );
259 if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT )
260 copy_len = cipher_get_block_size(ctx);
261
262 memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
263 copy_len );
264
265 ctx->unprocessed_len += copy_len;
266 ilen -= copy_len;
267 }
268
269 /*
270 * Process remaining full blocks
271 */
272 if( ilen )
273 {
274 if( 0 != ctx->cipher_info->cbc_func( ctx->cipher_ctx,
275 ctx->operation, ilen, ctx->iv, input, output ) )
276 {
277 return 1;
278 }
279 *olen += ilen;
280 }
281
282 return 0;
283 }
284
285 return 1;
286}
287
Paul Bakker23986e52011-04-24 08:57:21 +0000288static void add_pkcs_padding( unsigned char *output, size_t output_len,
289 size_t data_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000290{
Paul Bakker23986e52011-04-24 08:57:21 +0000291 size_t padding_len = output_len - data_len;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000292 unsigned char i = 0;
293
294 for( i = 0; i < padding_len; i++ )
Paul Bakker23986e52011-04-24 08:57:21 +0000295 output[data_len + i] = (unsigned char) padding_len;
Paul Bakker8123e9d2011-01-06 15:37:30 +0000296}
297
298static int get_pkcs_padding( unsigned char *input, unsigned char input_len,
Paul Bakker23986e52011-04-24 08:57:21 +0000299 size_t *data_len)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000300{
301 int i = 0;
302 unsigned char padding_len = 0;
303
Paul Bakkera885d682011-01-20 16:35:05 +0000304 if( NULL == input || NULL == data_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000305 return 1;
306
307 padding_len = input[input_len - 1];
308
Paul Bakkera885d682011-01-20 16:35:05 +0000309 if( padding_len > input_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000310 return 2;
311
Paul Bakkera885d682011-01-20 16:35:05 +0000312 for( i = input_len - padding_len; i < input_len; i++ )
313 if( input[i] != padding_len )
Paul Bakker8123e9d2011-01-06 15:37:30 +0000314 return 2;
315
316 *data_len = input_len - padding_len;
317
318 return 0;
319}
320
Paul Bakker23986e52011-04-24 08:57:21 +0000321int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen)
Paul Bakker8123e9d2011-01-06 15:37:30 +0000322{
323 if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
324 return 1;
325
326 *olen = 0;
327
328 if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )
329 {
330 if( POLARSSL_ENCRYPT == ctx->operation )
331 {
332 add_pkcs_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ),
333 ctx->unprocessed_len );
334 }
335 else if ( cipher_get_block_size( ctx ) != ctx->unprocessed_len )
336 {
337 /* For decrypt operations, expect a full block */
338 return 1;
339 }
340
341 /* cipher block */
342 if( 0 != ctx->cipher_info->cbc_func( ctx->cipher_ctx, ctx->operation,
343 cipher_get_block_size( ctx ), ctx->iv, ctx->unprocessed_data,
344 output ) )
345 {
346 return 1;
347 }
348
349 /* Set output size for decryption */
350 if( POLARSSL_DECRYPT == ctx->operation )
351 return get_pkcs_padding( output, cipher_get_block_size( ctx ), olen );
352
353 /* Set output size for encryption */
354 *olen = cipher_get_block_size( ctx );
355 return 0;
356 }
357
358 return 1;
359}
360
361#if defined(POLARSSL_SELF_TEST)
362
363#include <stdio.h>
364
365#define ASSERT(x) if (!(x)) { \
366 printf( "failed with %i at %s\n", value, (#x) ); \
367 return( 1 ); \
368}
369/*
370 * Checkup routine
371 */
372
373int cipher_self_test( int verbose )
374{
Paul Bakkerd61e7d92011-01-18 16:17:47 +0000375 ((void) verbose);
376
Paul Bakker8123e9d2011-01-06 15:37:30 +0000377 return( 0 );
378}
379
380#endif
381
382#endif