[BACK]Return to cipher-ctr.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/cipher-ctr.c, Revision 1.2.6.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.2.6.1 ! brad       17: RCSID("$OpenBSD: cipher-ctr.c,v 1.2 2003/06/17 18:14:23 markus Exp $");
1.1       markus     18:
                     19: #include <openssl/evp.h>
                     20:
                     21: #include "log.h"
                     22: #include "xmalloc.h"
                     23:
                     24: #if OPENSSL_VERSION_NUMBER < 0x00907000L
                     25: #include "rijndael.h"
                     26: #define AES_KEY rijndael_ctx
                     27: #define AES_BLOCK_SIZE 16
                     28: #define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b)
                     29: #define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1)
                     30: #else
                     31: #include <openssl/aes.h>
                     32: #endif
                     33:
                     34: const EVP_CIPHER *evp_aes_128_ctr(void);
                     35: void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
                     36:
                     37: struct ssh_aes_ctr_ctx
                     38: {
                     39:        AES_KEY         aes_ctx;
                     40:        u_char          aes_counter[AES_BLOCK_SIZE];
                     41: };
                     42:
                     43: /*
                     44:  * increment counter 'ctr',
                     45:  * the counter is of size 'len' bytes and stored in network-byte-order.
                     46:  * (LSB at ctr[len-1], MSB at ctr[0])
                     47:  */
                     48: static void
                     49: ssh_ctr_inc(u_char *ctr, u_int len)
                     50: {
                     51:        int i;
                     52:
                     53:        for (i = len - 1; i >= 0; i--)
                     54:                if (++ctr[i])   /* continue on overflow */
                     55:                        return;
                     56: }
                     57:
                     58: static int
                     59: ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
                     60:     u_int len)
                     61: {
                     62:        struct ssh_aes_ctr_ctx *c;
                     63:        u_int n = 0;
                     64:        u_char buf[AES_BLOCK_SIZE];
                     65:
                     66:        if (len == 0)
                     67:                return (1);
                     68:        if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
                     69:                return (0);
                     70:
                     71:        while ((len--) > 0) {
                     72:                if (n == 0) {
                     73:                        AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
                     74:                        ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
                     75:                }
                     76:                *(dest++) = *(src++) ^ buf[n];
                     77:                n = (n + 1) % AES_BLOCK_SIZE;
                     78:        }
                     79:        return (1);
                     80: }
                     81:
                     82: static int
                     83: ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
                     84:     int enc)
                     85: {
                     86:        struct ssh_aes_ctr_ctx *c;
                     87:
                     88:        if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
                     89:                c = xmalloc(sizeof(*c));
                     90:                EVP_CIPHER_CTX_set_app_data(ctx, c);
                     91:        }
                     92:        if (key != NULL)
                     93:                 AES_set_encrypt_key(key, ctx->key_len * 8, &c->aes_ctx);
                     94:        if (iv != NULL)
                     95:                memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
                     96:        return (1);
                     97: }
                     98:
                     99: static int
                    100: ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
                    101: {
                    102:        struct ssh_aes_ctr_ctx *c;
                    103:
                    104:        if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
                    105:                memset(c, 0, sizeof(*c));
                    106:                xfree(c);
                    107:                EVP_CIPHER_CTX_set_app_data(ctx, NULL);
                    108:        }
                    109:        return (1);
                    110: }
                    111:
                    112: void
                    113: ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
                    114: {
                    115:        struct ssh_aes_ctr_ctx *c;
                    116:
                    117:        if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
                    118:                fatal("ssh_aes_ctr_iv: no context");
                    119:        if (doset)
                    120:                memcpy(c->aes_counter, iv, len);
                    121:        else
                    122:                memcpy(iv, c->aes_counter, len);
                    123: }
                    124:
                    125: const EVP_CIPHER *
                    126: evp_aes_128_ctr(void)
                    127: {
                    128:        static EVP_CIPHER aes_ctr;
                    129:
                    130:        memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
                    131:        aes_ctr.nid = NID_undef;
                    132:        aes_ctr.block_size = AES_BLOCK_SIZE;
                    133:        aes_ctr.iv_len = AES_BLOCK_SIZE;
                    134:        aes_ctr.key_len = 16;
                    135:        aes_ctr.init = ssh_aes_ctr_init;
                    136:        aes_ctr.cleanup = ssh_aes_ctr_cleanup;
                    137:        aes_ctr.do_cipher = ssh_aes_ctr;
                    138:        aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
                    139:            EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
                    140:        return (&aes_ctr);
                    141: }