From d3c334c3d66efcf7724981c12e215cdf40883eed Mon Sep 17 00:00:00 2001 From: Simon Josefsson Date: Thu, 18 Jan 2007 11:20:17 +0000 Subject: [PATCH] Implement new _libssh2_cipher_* API. --- src/libgcrypt.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ src/libgcrypt.h | 24 +++++++++++++++++++ src/openssl.c | 31 +++++++++++++++++++++++++ src/openssl.h | 24 +++++++++++++++++++ 4 files changed, 141 insertions(+) diff --git a/src/libgcrypt.c b/src/libgcrypt.c index 9293fa9..6188216 100644 --- a/src/libgcrypt.c +++ b/src/libgcrypt.c @@ -151,3 +151,65 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, return (rc == 0) ? 0 : -1; } + +int _libssh2_cipher_init (_libssh2_cipher_ctx *h, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt) +{ + int mode = 0, keylen, err; + keylen = gcry_cipher_get_algo_keylen (algo); + if (algo != GCRY_CIPHER_ARCFOUR) + { + mode = GCRY_CIPHER_MODE_CBC; + } + + err = gcry_cipher_open (h, algo, mode, 0); + if (err) + { + return -1; + } + + err = gcry_cipher_setkey (*h, secret, keylen); + if (err) + { + return -1; + } + + if (algo != GCRY_CIPHER_ARCFOUR) + { + int blklen = gcry_cipher_get_algo_blklen (algo); + err = gcry_cipher_setiv (*h, iv, blklen); + if (err) + { + return -1; + } + } + return 0; +} + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block) +{ + size_t blklen = gcry_cipher_get_algo_blklen (algo); + int err; + if (blklen == 1) { +/* Hack for arcfour. */ + blklen = 8; + } + + if (encrypt) + { + err = gcry_cipher_encrypt (*ctx, block, blklen, + block, blklen); + } + else + { + err = gcry_cipher_decrypt (*ctx, block, blklen, + block, blklen); + } + return err; +} diff --git a/src/libgcrypt.h b/src/libgcrypt.h index 137604a..ce205ef 100644 --- a/src/libgcrypt.h +++ b/src/libgcrypt.h @@ -124,3 +124,27 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsa, unsigned long m_len); #define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) + +#define _libssh2_cipher_type(name) int name +#define _libssh2_cipher_ctx gcry_cipher_hd_t + +#define _libssh2_cipher_aes256 GCRY_CIPHER_AES256 +#define _libssh2_cipher_aes192 GCRY_CIPHER_AES192 +#define _libssh2_cipher_aes128 GCRY_CIPHER_AES128 +#define _libssh2_cipher_blowfish GCRY_CIPHER_BLOWFISH +#define _libssh2_cipher_arcfour GCRY_CIPHER_ARCFOUR +#define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5 +#define _libssh2_cipher_3des GCRY_CIPHER_3DES + +int _libssh2_cipher_init (_libssh2_cipher_ctx *h, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt); + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block); + +#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) diff --git a/src/openssl.c b/src/openssl.c index bfe6382..175c939 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -108,3 +108,34 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, return (ret == 1) ? 0 : -1; } + +int _libssh2_cipher_init (_libssh2_cipher_ctx *h, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt) +{ + EVP_CIPHER_CTX_init(h); + EVP_CipherInit(h, algo(), secret, iv, encrypt); + return 0; +} + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block) +{ + int blocksize = ctx->cipher->block_size; + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; + int ret; + + if (blocksize == 1) { +/* Hack for arcfour. */ + blocksize = 8; + } + ret = EVP_Cipher(ctx, buf, block, blocksize); + if (ret == 1) { + memcpy(block, buf, blocksize); + } + return ret == 1 ? 0 : 1; +} diff --git a/src/openssl.h b/src/openssl.h index 410bd00..62b42f7 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -161,3 +161,27 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, unsigned long m_len); #define _libssh2_dsa_free(dsactx) DSA_free(dsactx) + +#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void) +#define _libssh2_cipher_ctx EVP_CIPHER_CTX + +#define _libssh2_cipher_aes256 EVP_aes_256_cbc +#define _libssh2_cipher_aes192 EVP_aes_192_cbc +#define _libssh2_cipher_aes128 EVP_aes_128_cbc +#define _libssh2_cipher_blowfish EVP_bf_cbc +#define _libssh2_cipher_arcfour EVP_rc4 +#define _libssh2_cipher_cast5 EVP_cast5_cbc +#define _libssh2_cipher_3des EVP_des_ede3_cbc + +int _libssh2_cipher_init (_libssh2_cipher_ctx *h, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt); + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block); + +#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)