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