Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/cipher-ctr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4601 - (show annotations) (download) (as text)
Sun Aug 28 14:23:32 2011 UTC (20 months, 3 weeks ago) by maya
File MIME type: text/x-csrc
File size: 13529 byte(s)
Camellia を正式サポート
  "@openssh.org" 付きのほうはコメントアウトしたまま
1 /*
2 * Import from OpenSSH (TeraTerm Project 2008.11.18)
3 */
4 /* $OpenBSD: cipher-ctr.c,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
5 /*
6 * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20 #include <sys/types.h>
21 #include <malloc.h>
22 #include <string.h>
23
24 #include "config.h"
25
26 #include <openssl/evp.h>
27 #include <openssl/aes.h>
28 #include <openssl/des.h>
29 #include <openssl/blowfish.h>
30 #include <openssl/cast.h>
31 #include <openssl/camellia.h>
32
33 extern const EVP_CIPHER *evp_aes_128_ctr(void);
34 extern const EVP_CIPHER *evp_camellia_128_ctr(void);
35
36 struct ssh_aes_ctr_ctx
37 {
38 AES_KEY aes_ctx;
39 unsigned char aes_counter[AES_BLOCK_SIZE];
40 };
41
42 #define DES_BLOCK_SIZE sizeof(DES_cblock)
43 struct ssh_des3_ctr_ctx
44 {
45 DES_key_schedule des3_ctx[3];
46 unsigned char des3_counter[DES_BLOCK_SIZE];
47 };
48
49 struct ssh_blowfish_ctr_ctx
50 {
51 BF_KEY blowfish_ctx;
52 unsigned char blowfish_counter[BF_BLOCK];
53 };
54
55 struct ssh_cast5_ctr_ctx
56 {
57 CAST_KEY cast5_ctx;
58 unsigned char cast5_counter[CAST_BLOCK];
59 };
60
61 struct ssh_camellia_ctr_ctx
62 {
63 CAMELLIA_KEY camellia_ctx;
64 unsigned char camellia_counter[CAMELLIA_BLOCK_SIZE];
65 };
66
67 static void
68 ssh_ctr_inc(unsigned char *ctr, unsigned int len)
69 {
70 int i;
71
72 for ( i = len - 1; i>= 0; i--)
73 if (++ctr[i])
74 return;
75 }
76
77 //============================================================================
78 // AES
79 //============================================================================
80 static int
81 ssh_aes_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
82 {
83 struct ssh_aes_ctr_ctx *c;
84 unsigned int n = 0;
85 unsigned char buf[AES_BLOCK_SIZE];
86
87 if (len == 0)
88 return (1);
89 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
90 return (0);
91
92 while ((len--) > 0) {
93 if (n == 0) {
94 AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
95 ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
96 }
97 *(dest++) = *(src++) ^ buf[n];
98 n = (n + 1) % AES_BLOCK_SIZE;
99 }
100 return (1);
101 }
102
103 static int
104 ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
105 {
106 struct ssh_aes_ctr_ctx *c;
107
108 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
109 c = malloc(sizeof(*c));
110 EVP_CIPHER_CTX_set_app_data(ctx, c);
111 }
112 if (key != NULL)
113 AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, &c->aes_ctx);
114 if (iv != NULL)
115 memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
116 return (1);
117 }
118
119 static int
120 ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
121 {
122 struct ssh_aes_ctr_ctx *c;
123
124 if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
125 memset(c, 0, sizeof(*c));
126 free(c);
127 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
128 }
129 return (1);
130 }
131
132 const EVP_CIPHER *
133 evp_aes_128_ctr(void)
134 {
135 static EVP_CIPHER aes_ctr;
136
137 memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
138 aes_ctr.nid = NID_undef;
139 aes_ctr.block_size = AES_BLOCK_SIZE;
140 aes_ctr.iv_len = AES_BLOCK_SIZE;
141 aes_ctr.key_len = 16;
142 aes_ctr.init = ssh_aes_ctr_init;
143 aes_ctr.cleanup = ssh_aes_ctr_cleanup;
144 aes_ctr.do_cipher = ssh_aes_ctr;
145 #ifndef SSH_OLD_EVP
146 aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
147 #endif
148 return (&aes_ctr);
149 }
150
151 //============================================================================
152 // Triple-DES
153 //============================================================================
154 static int
155 ssh_des3_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
156 {
157 struct ssh_des3_ctr_ctx *c;
158 unsigned int n = 0;
159 unsigned char buf[DES_BLOCK_SIZE];
160
161 if (len == 0)
162 return (1);
163 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
164 return (0);
165
166 while ((len--) > 0) {
167 if (n == 0) {
168 memcpy(buf, (unsigned char *)(c->des3_counter), DES_BLOCK_SIZE);
169 DES_encrypt3((DES_LONG *)buf, &c->des3_ctx[0], &c->des3_ctx[1], &c->des3_ctx[2]);
170 ssh_ctr_inc(c->des3_counter, DES_BLOCK_SIZE);
171 }
172 *(dest++) = *(src++) ^ buf[n];
173 n = (n + 1) % DES_BLOCK_SIZE;
174 }
175 return (1);
176 }
177
178 static int
179 ssh_des3_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
180 {
181 struct ssh_des3_ctr_ctx *c;
182
183 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
184 c = malloc(sizeof(*c));
185 EVP_CIPHER_CTX_set_app_data(ctx, c);
186 }
187 if (key != NULL) {
188 DES_set_key((const_DES_cblock *)key, &c->des3_ctx[0]);
189 DES_set_key((const_DES_cblock *)(key + 8), &c->des3_ctx[1]);
190 DES_set_key((const_DES_cblock *)(key + 16), &c->des3_ctx[2]);
191 }
192
193 if (iv != NULL)
194 memcpy(c->des3_counter, iv, DES_BLOCK_SIZE);
195 return (1);
196 }
197
198 static int
199 ssh_des3_ctr_cleanup(EVP_CIPHER_CTX *ctx)
200 {
201 struct ssh_des3_ctr_ctx *c;
202
203 if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
204 memset(c, 0, sizeof(*c));
205 free(c);
206 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
207 }
208 return (1);
209 }
210
211 const EVP_CIPHER *
212 evp_des3_ctr(void)
213 {
214 static EVP_CIPHER des3_ctr;
215
216 memset(&des3_ctr, 0, sizeof(EVP_CIPHER));
217 des3_ctr.nid = NID_undef;
218 des3_ctr.block_size = DES_BLOCK_SIZE;
219 des3_ctr.iv_len = DES_BLOCK_SIZE;
220 des3_ctr.key_len = 24;
221 des3_ctr.init = ssh_des3_ctr_init;
222 des3_ctr.cleanup = ssh_des3_ctr_cleanup;
223 des3_ctr.do_cipher = ssh_des3_ctr;
224 #ifndef SSH_OLD_EVP
225 des3_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
226 #endif
227 return (&des3_ctr);
228 }
229
230 //============================================================================
231 // Blowfish
232 //============================================================================
233 static int
234 ssh_bf_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
235 {
236 struct ssh_blowfish_ctr_ctx *c;
237 unsigned int n = 0;
238 unsigned char buf[BF_BLOCK];
239 int i, j;
240 BF_LONG tmp[(BF_BLOCK + 3) / 4];
241 unsigned char *p;
242
243 if (len == 0)
244 return (1);
245 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
246 return (0);
247
248 while ((len--) > 0) {
249 if (n == 0) {
250 for (i = j = 0, p = c->blowfish_counter; i < BF_BLOCK; i += 4, j++) {
251 tmp[j] = ((BF_LONG)*p++) << 24;
252 tmp[j] |= ((BF_LONG)*p++) << 16;
253 tmp[j] |= ((BF_LONG)*p++) << 8;
254 tmp[j] |= ((BF_LONG)*p++);
255 }
256
257 BF_encrypt(tmp, &c->blowfish_ctx);
258
259 for (i = j = 0, p = buf; i < BF_BLOCK; i += 4, j++) {
260 *p++ = (unsigned char)(tmp[j] >> 24);
261 *p++ = (unsigned char)(tmp[j] >> 16);
262 *p++ = (unsigned char)(tmp[j] >> 8);
263 *p++ = (unsigned char)tmp[j];
264 }
265
266 ssh_ctr_inc(c->blowfish_counter, BF_BLOCK);
267 }
268 *(dest++) = *(src++) ^ buf[n];
269 n = (n + 1) % BF_BLOCK;
270 }
271 return (1);
272 }
273
274 static int
275 ssh_bf_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
276 {
277 struct ssh_blowfish_ctr_ctx *c;
278
279 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
280 c = malloc(sizeof(*c));
281 EVP_CIPHER_CTX_set_app_data(ctx, c);
282 }
283 if (key != NULL) {
284 BF_set_key(&c->blowfish_ctx, EVP_CIPHER_CTX_key_length(ctx), key);
285 }
286
287 if (iv != NULL)
288 memcpy(c->blowfish_counter, iv, BF_BLOCK);
289 return (1);
290 }
291
292 static int
293 ssh_bf_ctr_cleanup(EVP_CIPHER_CTX *ctx)
294 {
295 struct ssh_blowfish_ctr_ctx *c;
296
297 if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
298 memset(c, 0, sizeof(*c));
299 free(c);
300 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
301 }
302 return (1);
303 }
304
305 const EVP_CIPHER *
306 evp_bf_ctr(void)
307 {
308 static EVP_CIPHER blowfish_ctr;
309
310 memset(&blowfish_ctr, 0, sizeof(EVP_CIPHER));
311 blowfish_ctr.nid = NID_undef;
312 blowfish_ctr.block_size = BF_BLOCK;
313 blowfish_ctr.iv_len = BF_BLOCK;
314 blowfish_ctr.key_len = 16;
315 blowfish_ctr.init = ssh_bf_ctr_init;
316 blowfish_ctr.cleanup = ssh_bf_ctr_cleanup;
317 blowfish_ctr.do_cipher = ssh_bf_ctr;
318 #ifndef SSH_OLD_EVP
319 blowfish_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
320 #endif
321 return (&blowfish_ctr);
322 }
323
324 //============================================================================
325 // CAST-128
326 //============================================================================
327 static int
328 ssh_cast5_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
329 {
330 struct ssh_cast5_ctr_ctx *c;
331 unsigned int n = 0;
332 unsigned char buf[CAST_BLOCK];
333 int i, j;
334 CAST_LONG tmp[(CAST_BLOCK + 3) / 4];
335 unsigned char *p;
336
337 if (len == 0)
338 return (1);
339 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
340 return (0);
341
342 while ((len--) > 0) {
343 if (n == 0) {
344 for (i = j = 0, p = c->cast5_counter; i < CAST_BLOCK; i += 4, j++) {
345 tmp[j] = ((CAST_LONG)*p++) << 24;
346 tmp[j] |= ((CAST_LONG)*p++) << 16;
347 tmp[j] |= ((CAST_LONG)*p++) << 8;
348 tmp[j] |= ((CAST_LONG)*p++);
349 }
350
351 CAST_encrypt(tmp, &c->cast5_ctx);
352
353 for (i = j = 0, p = buf; i < CAST_BLOCK; i += 4, j++) {
354 *p++ = (unsigned char)(tmp[j] >> 24);
355 *p++ = (unsigned char)(tmp[j] >> 16);
356 *p++ = (unsigned char)(tmp[j] >> 8);
357 *p++ = (unsigned char)tmp[j];
358 }
359
360 ssh_ctr_inc(c->cast5_counter, CAST_BLOCK);
361 }
362 *(dest++) = *(src++) ^ buf[n];
363 n = (n + 1) % CAST_BLOCK;
364 }
365 return (1);
366 }
367
368 static int
369 ssh_cast5_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
370 {
371 struct ssh_cast5_ctr_ctx *c;
372
373 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
374 c = malloc(sizeof(*c));
375 EVP_CIPHER_CTX_set_app_data(ctx, c);
376 }
377 if (key != NULL) {
378 CAST_set_key(&c->cast5_ctx, EVP_CIPHER_CTX_key_length(ctx), key);
379 }
380
381 if (iv != NULL)
382 memcpy(c->cast5_counter, iv, CAST_BLOCK);
383 return (1);
384 }
385
386 static int
387 ssh_cast5_ctr_cleanup(EVP_CIPHER_CTX *ctx)
388 {
389 struct ssh_cast5_ctr_ctx *c;
390
391 if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
392 memset(c, 0, sizeof(*c));
393 free(c);
394 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
395 }
396 return (1);
397 }
398
399 const EVP_CIPHER *
400 evp_cast5_ctr(void)
401 {
402 static EVP_CIPHER cast5_ctr;
403
404 memset(&cast5_ctr, 0, sizeof(EVP_CIPHER));
405 cast5_ctr.nid = NID_undef;
406 cast5_ctr.block_size = CAST_BLOCK;
407 cast5_ctr.iv_len = CAST_BLOCK;
408 cast5_ctr.key_len = 16;
409 cast5_ctr.init = ssh_cast5_ctr_init;
410 cast5_ctr.cleanup = ssh_cast5_ctr_cleanup;
411 cast5_ctr.do_cipher = ssh_cast5_ctr;
412 #ifndef SSH_OLD_EVP
413 cast5_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
414 #endif
415 return (&cast5_ctr);
416 }
417
418 //============================================================================
419 // Camellia
420 //============================================================================
421 static int
422 ssh_camellia_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
423 {
424 struct ssh_camellia_ctr_ctx *c;
425 unsigned int n = 0;
426 unsigned char buf[CAMELLIA_BLOCK_SIZE];
427
428 if (len == 0)
429 return (1);
430 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
431 return (0);
432
433 while ((len--) > 0) {
434 if (n == 0) {
435 Camellia_encrypt(c->camellia_counter, buf, &c->camellia_ctx);
436 ssh_ctr_inc(c->camellia_counter, CAMELLIA_BLOCK_SIZE);
437 }
438 *(dest++) = *(src++) ^ buf[n];
439 n = (n + 1) % CAMELLIA_BLOCK_SIZE;
440 }
441 return (1);
442 }
443
444 static int
445 ssh_camellia_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
446 {
447 struct ssh_camellia_ctr_ctx *c;
448
449 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
450 c = malloc(sizeof(*c));
451 EVP_CIPHER_CTX_set_app_data(ctx, c);
452 }
453 if (key != NULL)
454 Camellia_set_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, &c->camellia_ctx);
455 if (iv != NULL)
456 memcpy(c->camellia_counter, iv, CAMELLIA_BLOCK_SIZE);
457 return (1);
458 }
459
460 static int
461 ssh_camellia_ctr_cleanup(EVP_CIPHER_CTX *ctx)
462 {
463 struct ssh_camellia_ctr_ctx *c;
464
465 if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
466 memset(c, 0, sizeof(*c));
467 free(c);
468 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
469 }
470 return (1);
471 }
472
473 void
474 ssh_camellia_ctr_iv(EVP_CIPHER_CTX *evp, int doset, unsigned char * iv, unsigned int len)
475 {
476 struct ssh_camellia_ctr_ctx *c;
477
478 if ((c = EVP_CIPHER_CTX_get_app_data(evp)) != NULL)
479 if(doset)
480 memcpy(c->camellia_counter, iv, len);
481 else
482 memcpy(iv, c->camellia_counter, len);
483 }
484
485 const EVP_CIPHER *
486 evp_camellia_128_ctr(void)
487 {
488 static EVP_CIPHER camellia_ctr;
489
490 memset(&camellia_ctr, 0, sizeof(EVP_CIPHER));
491 camellia_ctr.nid = NID_undef;
492 camellia_ctr.block_size = CAMELLIA_BLOCK_SIZE;
493 camellia_ctr.iv_len = CAMELLIA_BLOCK_SIZE;
494 camellia_ctr.key_len = 16;
495 camellia_ctr.init = ssh_camellia_ctr_init;
496 camellia_ctr.cleanup = ssh_camellia_ctr_cleanup;
497 camellia_ctr.do_cipher = ssh_camellia_ctr;
498 #ifndef SSH_OLD_EVP
499 camellia_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
500 #endif
501 return (&camellia_ctr);
502 }

SourceForge.JP is a Japanese version of SourceForge.net. For developments that are not related to Japan, we recommend you to use SourceForge.net.