X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=crypt.c;h=f1e42d4a228f7c0c498ac505575b6a0f3667bf27;hp=34b78798cc764451e71d1a61353e52485cbd92e0;hb=a85b3b947174c64ce06b4d6e438677055bf3f1ae;hpb=d9f54f439c98aed8b974f55acd468bdae424683f diff --git a/crypt.c b/crypt.c index 34b78798..f1e42d4a 100644 --- a/crypt.c +++ b/crypt.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -61,31 +60,24 @@ void init_random_seed_or_die(void) srandom(seed); } -static EVP_PKEY *load_key(const char *file) +static int get_private_key(const char *path, RSA **rsa) { - BIO *key; - EVP_PKEY *pkey = NULL; + EVP_PKEY *pkey; + BIO *bio = BIO_new(BIO_s_file()); - key = BIO_new(BIO_s_file()); - if (!key) - return NULL; - if (BIO_read_filename(key, file) > 0) - pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL); - BIO_free(key); - return pkey; -} - -static int get_private_key(const char *key_file, RSA **rsa) -{ - EVP_PKEY *key = load_key(key_file); - - if (!key) + *rsa = NULL; + if (!bio) return -E_PRIVATE_KEY; - *rsa = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); - if (!*rsa) - return -E_RSA; - return RSA_size(*rsa); + if (BIO_read_filename(bio, path) <= 0) + goto bio_free; + pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + if (!pkey) + goto bio_free; + *rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); +bio_free: + BIO_free(bio); + return *rsa? RSA_size(*rsa) : -E_PRIVATE_KEY; } /* @@ -252,26 +244,16 @@ int pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf, } struct stream_cipher { - bool use_aes; - union { - RC4_KEY rc4_key; - EVP_CIPHER_CTX *aes; - } context; + EVP_CIPHER_CTX *aes; }; -struct stream_cipher *sc_new(const unsigned char *data, int len, - bool use_aes) +struct stream_cipher *sc_new(const unsigned char *data, int len) { struct stream_cipher *sc = para_malloc(sizeof(*sc)); - sc->use_aes = use_aes; - if (!use_aes) { - RC4_set_key(&sc->context.rc4_key, len, data); - return sc; - } assert(len >= 2 * AES_CRT128_BLOCK_SIZE); - sc->context.aes = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(sc->context.aes, EVP_aes_128_ctr(), NULL, data, + sc->aes = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(sc->aes, EVP_aes_128_ctr(), NULL, data, data + AES_CRT128_BLOCK_SIZE); return sc; } @@ -280,40 +262,10 @@ void sc_free(struct stream_cipher *sc) { if (!sc) return; - EVP_CIPHER_CTX_free(sc->context.aes); + EVP_CIPHER_CTX_free(sc->aes); free(sc); } -/** - * The RC4() implementation of openssl apparently reads and writes data in - * blocks of 8 bytes. So we have to make sure our buffer sizes are a multiple - * of this. - */ -#define RC4_ALIGN 8 - -static void rc4_crypt(RC4_KEY *key, struct iovec *src, struct iovec *dst) -{ - size_t len = src->iov_len, l1, l2; - - assert(len > 0); - assert(len < ((typeof(src->iov_len))-1) / 2); - l1 = ROUND_DOWN(len, RC4_ALIGN); - l2 = ROUND_UP(len, RC4_ALIGN); - - *dst = (typeof(*dst)) { - /* Add one for the terminating zero byte. */ - .iov_base = para_malloc(l2 + 1), - .iov_len = len - }; - RC4(key, l1, src->iov_base, dst->iov_base); - if (len > l1) { - unsigned char remainder[RC4_ALIGN] = ""; - memcpy(remainder, src->iov_base + l1, len - l1); - RC4(key, len - l1, remainder, dst->iov_base + l1); - } - ((char *)dst->iov_base)[len] = '\0'; -} - static void aes_ctr128_crypt(EVP_CIPHER_CTX *ctx, struct iovec *src, struct iovec *dst) { @@ -335,9 +287,7 @@ static void aes_ctr128_crypt(EVP_CIPHER_CTX *ctx, struct iovec *src, void sc_crypt(struct stream_cipher *sc, struct iovec *src, struct iovec *dst) { - if (sc->use_aes) - return aes_ctr128_crypt(sc->context.aes, src, dst); - return rc4_crypt(&sc->context.rc4_key, src, dst); + return aes_ctr128_crypt(sc->aes, src, dst); } void hash_function(const char *data, unsigned long len, unsigned char *hash)