| diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c |
| |
| |
| @@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in |
| |
| struct ssh_aes_ctr_ctx |
| { |
| - AES_KEY aes_ctx; |
| + EVP_CIPHER_CTX ecbctx; |
| u_char aes_counter[AES_BLOCK_SIZE]; |
| }; |
| |
| @@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char |
| { |
| struct ssh_aes_ctr_ctx *c; |
| size_t n = 0; |
| - u_char buf[AES_BLOCK_SIZE]; |
| + u_char ctrbuf[AES_BLOCK_SIZE*256]; |
| + u_char buf[AES_BLOCK_SIZE*256]; |
| |
| if (len == 0) |
| return (1); |
| if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) |
| return (0); |
| |
| - while ((len--) > 0) { |
| + for (; len > 0; len -= sizeof(u_int)) { |
| + u_int r,a,b; |
| + |
| if (n == 0) { |
| - AES_encrypt(c->aes_counter, buf, &c->aes_ctx); |
| - ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); |
| + int outl, i, buflen; |
| + |
| + buflen = MIN(len, sizeof(ctrbuf)); |
| + |
| + for(i = 0; i < buflen; i += AES_BLOCK_SIZE) { |
| + memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE); |
| + ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); |
| + } |
| + |
| + EVP_EncryptUpdate(&c->ecbctx, buf, &outl, |
| + ctrbuf, buflen); |
| } |
| - *(dest++) = *(src++) ^ buf[n]; |
| - n = (n + 1) % AES_BLOCK_SIZE; |
| + |
| + memcpy(&a, src, sizeof(a)); |
| + memcpy(&b, &buf[n], sizeof(b)); |
| + r = a ^ b; |
| + memcpy(dest, &r, sizeof(r)); |
| + src += sizeof(a); |
| + dest += sizeof(r); |
| + |
| + n = (n + sizeof(b)) % sizeof(buf); |
| } |
| + memset(ctrbuf, '\0', sizeof(ctrbuf)); |
| + memset(buf, '\0', sizeof(buf)); |
| return (1); |
| } |
| |
| @@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co |
| c = xmalloc(sizeof(*c)); |
| EVP_CIPHER_CTX_set_app_data(ctx, c); |
| } |
| - if (key != NULL) |
| - AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, |
| - &c->aes_ctx); |
| + |
| + EVP_CIPHER_CTX_init(&c->ecbctx); |
| + |
| + if (key != NULL) { |
| + const EVP_CIPHER *cipher; |
| + switch(EVP_CIPHER_CTX_key_length(ctx)*8) { |
| + case 128: |
| + cipher = EVP_aes_128_ecb(); |
| + break; |
| + case 192: |
| + cipher = EVP_aes_192_ecb(); |
| + break; |
| + case 256: |
| + cipher = EVP_aes_256_ecb(); |
| + break; |
| + default: |
| + fatal("ssh_aes_ctr_init: wrong aes key length"); |
| + } |
| + if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL)) |
| + fatal("ssh_aes_ctr_init: cannot initialize aes encryption"); |
| + EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0); |
| + } |
| if (iv != NULL) |
| memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); |
| return (1); |
| @@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) |
| struct ssh_aes_ctr_ctx *c; |
| |
| if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { |
| + EVP_CIPHER_CTX_cleanup(&c->ecbctx); |
| memset(c, 0, sizeof(*c)); |
| free(c); |
| EVP_CIPHER_CTX_set_app_data(ctx, NULL); |