Annotation of src/usr.bin/ssh/cipher-ctr.c, Revision 1.4.4.1
1.1 markus 1: /*
1.2 markus 2: * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
1.1 markus 3: *
1.2 markus 4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
1.1 markus 7: *
1.2 markus 8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 markus 15: */
16: #include "includes.h"
1.4.4.1 ! brad 17: RCSID("$OpenBSD: cipher-ctr.c,v 1.5 2004/12/22 02:13:19 djm Exp $");
1.1 markus 18:
19: #include <openssl/evp.h>
1.4.4.1 ! brad 20: #include <openssl/aes.h>
1.1 markus 21:
22: #include "log.h"
23: #include "xmalloc.h"
24:
25: const EVP_CIPHER *evp_aes_128_ctr(void);
26: void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
27:
28: struct ssh_aes_ctr_ctx
29: {
30: AES_KEY aes_ctx;
31: u_char aes_counter[AES_BLOCK_SIZE];
32: };
33:
34: /*
35: * increment counter 'ctr',
36: * the counter is of size 'len' bytes and stored in network-byte-order.
37: * (LSB at ctr[len-1], MSB at ctr[0])
38: */
39: static void
40: ssh_ctr_inc(u_char *ctr, u_int len)
41: {
42: int i;
43:
44: for (i = len - 1; i >= 0; i--)
45: if (++ctr[i]) /* continue on overflow */
46: return;
47: }
48:
49: static int
50: ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
51: u_int len)
52: {
53: struct ssh_aes_ctr_ctx *c;
54: u_int n = 0;
55: u_char buf[AES_BLOCK_SIZE];
56:
57: if (len == 0)
58: return (1);
59: if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
60: return (0);
61:
62: while ((len--) > 0) {
63: if (n == 0) {
64: AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
65: ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
66: }
67: *(dest++) = *(src++) ^ buf[n];
68: n = (n + 1) % AES_BLOCK_SIZE;
69: }
70: return (1);
71: }
72:
73: static int
74: ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
75: int enc)
76: {
77: struct ssh_aes_ctr_ctx *c;
78:
79: if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
80: c = xmalloc(sizeof(*c));
81: EVP_CIPHER_CTX_set_app_data(ctx, c);
82: }
83: if (key != NULL)
1.4 dtucker 84: AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
85: &c->aes_ctx);
1.1 markus 86: if (iv != NULL)
87: memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
88: return (1);
89: }
90:
91: static int
92: ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
93: {
94: struct ssh_aes_ctr_ctx *c;
95:
96: if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
97: memset(c, 0, sizeof(*c));
98: xfree(c);
99: EVP_CIPHER_CTX_set_app_data(ctx, NULL);
100: }
101: return (1);
102: }
103:
104: void
105: ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
106: {
107: struct ssh_aes_ctr_ctx *c;
108:
109: if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
110: fatal("ssh_aes_ctr_iv: no context");
111: if (doset)
112: memcpy(c->aes_counter, iv, len);
113: else
114: memcpy(iv, c->aes_counter, len);
115: }
116:
117: const EVP_CIPHER *
118: evp_aes_128_ctr(void)
119: {
120: static EVP_CIPHER aes_ctr;
121:
122: memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
123: aes_ctr.nid = NID_undef;
124: aes_ctr.block_size = AES_BLOCK_SIZE;
125: aes_ctr.iv_len = AES_BLOCK_SIZE;
126: aes_ctr.key_len = 16;
127: aes_ctr.init = ssh_aes_ctr_init;
128: aes_ctr.cleanup = ssh_aes_ctr_cleanup;
129: aes_ctr.do_cipher = ssh_aes_ctr;
130: aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
131: EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
132: return (&aes_ctr);
133: }