Loading src/common/Makefile.am +2 −2 Original line number Diff line number Diff line Loading @@ -3,9 +3,9 @@ noinst_LIBRARIES = libor.a #CFLAGS = -Wall -Wpointer-arith -O2 libor_a_SOURCES = config.c key.c log.c utils.c crypto.c libor_a_SOURCES = config.c log.c utils.c crypto.c noinst_HEADERS = config.h key.h log.h \ noinst_HEADERS = config.h log.h \ policies.h utils.h \ ss.h version.h crypto.h src/common/crypto.c +129 −17 Original line number Diff line number Diff line Loading @@ -2,11 +2,21 @@ /* See LICENSE for licensing information */ /* $Id$ */ #include "crypto.h" #include <string.h> #include <openssl/err.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> #include <openssl/rand.h> #include <stdlib.h> #include <assert.h> #include "crypto.h" #include "config.h" #include "log.h" int crypto_global_init() { ERR_load_crypto_strings(); Loading Loading @@ -201,8 +211,9 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src) switch(env->type) { case CRYPTO_PK_RSA: /* if (env->key) RSA_free((RSA *)env->key); RSA_free((RSA *)env->key);*/ env->key = (unsigned char *)PEM_read_RSAPrivateKey(src, (RSA **)&env->key, NULL, NULL); if (!env->key) return -1; Loading @@ -213,14 +224,60 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src) return 0; } int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile) { FILE *f_pr; int retval = 0; assert(env && keyfile); if (strspn(keyfile,CONFIG_LEGAL_FILENAME_CHARACTERS) == strlen(keyfile)) /* filename contains legal characters only */ { /* open the keyfile */ f_pr=fopen(keyfile,"r"); if (!f_pr) return -1; /* read the private key */ retval = crypto_pk_read_private_key(env, f_pr); fclose(f_pr); if (retval == -1) { log(LOG_ERR,"Error reading private key : %s",crypto_perror()); return -1; } /* check the private key */ retval = crypto_pk_check_key(env); if (retval == 0) { log(LOG_ERR,"Private key read but is invalid : %s.", crypto_perror()); return -1; } else if (retval == -1) { log(LOG_ERR,"Private key read but validity checking failed : %s",crypto_perror()); return -1; } else if (retval == 1) { return 0; } } /* filename contains legal characters only */ return -1; /* report error */ } int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src) { assert(env && src); switch(env->type) { case CRYPTO_PK_RSA: /* if (env->key) RSA_free((RSA *)env->key); RSA_free((RSA *)env->key);*/ env->key = (unsigned char *)PEM_read_RSAPublicKey(src, (RSA **)&env->key, NULL, NULL); if (!env->key) return -1; Loading Loading @@ -285,9 +342,9 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key) switch(env->type) { case CRYPTO_PK_RSA: if (env->key) RSA_free((RSA *)env->key); env->key = key; if (!env->key) return -1; memcpy((void *)env->key, (void *)key, sizeof(RSA)); break; default : return -1; Loading @@ -296,6 +353,36 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key) return 0; } int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) { int result; if (!a || !b) return -1; if (!a->key || !b->key) return -1; if (a->type != b->type) return -1; switch(a->type) { case CRYPTO_PK_RSA: assert(((RSA *)a->key)->n && ((RSA *)a->key)->e && ((RSA *)b->key)->n && ((RSA *)b->key)->e); result = BN_cmp(((RSA *)a->key)->n, ((RSA *)b->key)->n); if (result) return result; return BN_cmp(((RSA *)a->key)->e, ((RSA *)b->key)->e); default: return -1; } } int crypto_pk_keysize(crypto_pk_env_t *env) { assert(env && env->key); return RSA_size((RSA *)env->key); } int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding) { assert(env && from && to); Loading @@ -321,6 +408,23 @@ int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *from, int fro } /* symmetric crypto */ int crypto_cipher_generate_key(crypto_cipher_env_t *env) { assert(env); switch(env->type) { case CRYPTO_CIPHER_IDENTITY: return 0; case CRYPTO_CIPHER_DES: return crypto_rand(8, env->key); case CRYPTO_CIPHER_RC4: return crypto_rand(16, env->key); default: return -1; } } int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv) { assert(env && iv); Loading @@ -329,10 +433,14 @@ int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv) case CRYPTO_CIPHER_IDENTITY: break; case CRYPTO_CIPHER_DES: if (!env->iv) return -1; memcpy((void *)env->iv, (void *)iv, 8); break; case CRYPTO_CIPHER_RC4: if (env->iv) free((void *)env->iv); env->iv = iv; if (!env->iv) return -1; memcpy((void *)env->iv, (void *)iv, 16); break; default: return -1; Loading @@ -348,10 +456,14 @@ int crypto_cipher_set_key(crypto_cipher_env_t *env, unsigned char *key) case CRYPTO_CIPHER_IDENTITY: break; case CRYPTO_CIPHER_DES: if (!env->key) return -1; memcpy((void *)env->key, (void *)key, 8); break; case CRYPTO_CIPHER_RC4: if (env->key) free((void *)env->key); env->key = key; if (!env->key) return -1; memcpy((void *)env->key, (void *)key, 16); break; default: return -1; Loading Loading @@ -396,7 +508,7 @@ int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env) return 0; } int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, size_t fromlen, unsigned char *to) { int tolen; Loading @@ -405,7 +517,7 @@ int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, unsigne return !(EVP_EncryptUpdate((EVP_CIPHER_CTX *)env->aux, to, &tolen, from, fromlen)); } int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *from, size_t fromlen, unsigned char *to) { int tolen; Loading @@ -425,7 +537,7 @@ int crypto_SHA_digest(unsigned char *m, int len, unsigned char *digest) int crypto_rand(unsigned int n, unsigned char *to) { assert(to); return (RAND_bytes(to, n) == -1); return (RAND_bytes(to, n) != 1); } int crypto_pseudo_rand(unsigned int n, unsigned char *to) Loading src/common/crypto.h +5 −4 Original line number Diff line number Diff line Loading @@ -5,11 +5,8 @@ #ifndef __CRYPTO_H #define __CRYPTO_H #include <openssl/err.h> #include <stdio.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> #include <openssl/rand.h> /* available encryption primitives */ #define CRYPTO_CIPHER_IDENTITY 0 Loading Loading @@ -54,13 +51,17 @@ int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src); int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest); int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest); int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile); int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key); int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b); int crypto_pk_keysize(crypto_pk_env_t *env); int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding); int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding); /* symmetric crypto */ int crypto_cipher_generate_key(crypto_cipher_env_t *env); int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv); int crypto_cipher_set_key(crypto_cipher_env_t *env, unsigned char *key); int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env); Loading src/or/cell.c +2 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,8 @@ static cell_t *new_create_cell(uint16_t aci, unsigned char length, unsigned char c->seq = 0; memcpy((void *)c->payload, (void *)buf, length); retval = RAND_pseudo_bytes((unsigned char *)(c->payload+length),CELL_PAYLOAD_SIZE-length); if (retval == -1) /* RAND_pseudo_bytes() error */ retval = crypto_pseudo_rand(CELL_PAYLOAD_SIZE-length, (unsigned char *)(c->payload+length)); if (retval) /* RAND_pseudo_bytes() error */ { free((void *)c); return NULL; Loading src/or/circuit.c +62 −41 Original line number Diff line number Diff line Loading @@ -67,8 +67,10 @@ circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) { void circuit_free(circuit_t *circ) { EVP_CIPHER_CTX_cleanup(&circ->n_ctx); EVP_CIPHER_CTX_cleanup(&circ->p_ctx); if (circ->n_crypto) crypto_free_cipher_env(circ->n_crypto); if (circ->p_crypto) crypto_free_cipher_env(circ->p_crypto); if(circ->onion) free(circ->onion); Loading @@ -93,7 +95,7 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) { log(LOG_DEBUG,"get_unique_aci_by_addr_port() trying to get a unique aci"); RAND_pseudo_bytes((unsigned char *)&test_aci, 2); crypto_pseudo_rand(2, (unsigned char *)&test_aci); if(aci_type == ACI_TYPE_LOWER) test_aci &= htons(0x00FF); Loading @@ -117,7 +119,7 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) { int circuit_init(circuit_t *circ, int aci_type) { onion_layer_t *ol; int retval = 0; unsigned char iv[16]; unsigned char digest1[20]; unsigned char digest2[20]; Loading @@ -143,32 +145,23 @@ int circuit_init(circuit_t *circ, int aci_type) { log(LOG_DEBUG,"circuit_init(): Chosen ACI %u.",circ->n_aci); /* keys */ SHA1(ol->keyseed,16,digest1); SHA1(digest1,20,digest2); SHA1(digest2,20,digest1); memcpy(circ->p_key,digest2,16); memcpy(circ->n_key,digest1,16); memset((void *)iv, 0, 16); crypto_SHA_digest(ol->keyseed,16,digest1); crypto_SHA_digest(digest1,20,digest2); crypto_SHA_digest(digest2,20,digest1); log(LOG_DEBUG,"circuit_init(): Computed keys."); /* set IVs to zero */ memset(circ->n_iv,0,16); memset(circ->p_iv,0,16); /* initialize cipher context */ EVP_CIPHER_CTX_init(&circ->n_ctx); EVP_CIPHER_CTX_init(&circ->p_ctx); /* initialize crypto engines */ switch(circ->p_f) { case ONION_CIPHER_DES : retval = EVP_EncryptInit(&circ->p_ctx, EVP_des_ofb(), circ->p_key, circ->p_iv); circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); break; case ONION_CIPHER_RC4 : retval = EVP_EncryptInit(&circ->p_ctx, EVP_rc4(), circ->p_key,circ->p_iv); circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); break; case ONION_CIPHER_IDENTITY : retval = EVP_EncryptInit(&circ->p_ctx, EVP_enc_null(), circ->p_key, circ->p_iv); circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY); break; default : log(LOG_ERR,"Onion contains unrecognized cipher(%u) for ACI : %u.",circ->p_f,circ->n_aci); Loading @@ -176,36 +169,65 @@ int circuit_init(circuit_t *circ, int aci_type) { break; } if (!retval) /* EVP_EncryptInit() error */ if (!circ->p_crypto) { log(LOG_ERR,"Could not create a cryptographic environment."); return -1; } if (crypto_cipher_set_iv(circ->p_crypto, iv) == -1) { log(LOG_ERR,"Could not set the IV."); crypto_free_cipher_env(circ->p_crypto); return -1; } if (crypto_cipher_set_key(circ->p_crypto, digest2) == -1) { log(LOG_ERR,"Could not set encryption key."); crypto_free_cipher_env(circ->p_crypto); return -1; } if (crypto_cipher_encrypt_init_cipher(circ->p_crypto)) /* crypto_cipher_init_cipher error */ { log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci); EVP_CIPHER_CTX_cleanup(&circ->n_ctx); EVP_CIPHER_CTX_cleanup(&circ->p_ctx); crypto_free_cipher_env(circ->p_crypto); return -1; } switch(circ->n_f) { case ONION_CIPHER_DES : retval = EVP_DecryptInit(&circ->n_ctx, EVP_des_ofb(), circ->n_key, circ->n_iv); circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); break; case ONION_CIPHER_RC4 : retval = EVP_DecryptInit(&circ->n_ctx, EVP_rc4(), circ->n_key,circ->n_iv); circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); break; case ONION_CIPHER_IDENTITY : retval = EVP_DecryptInit(&circ->n_ctx, EVP_enc_null(), circ->n_key, circ->n_iv); circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY); break; default : log(LOG_ERR,"Onion contains unrecognized cipher for ACI : %u.",circ->n_aci); log(LOG_ERR,"Onion contains unrecognized cipher(%u) for ACI : %u.",circ->n_f,circ->n_aci); return -1; break; } if (!retval) /* EVP_EncryptInit() error */ if (!circ->n_crypto) { log(LOG_ERR,"Could not create a cryptographic environment."); return -1; } if (crypto_cipher_set_iv(circ->n_crypto, iv) == -1) { log(LOG_ERR,"Could not set the IV."); crypto_free_cipher_env(circ->n_crypto); return -1; } if (crypto_cipher_set_key(circ->n_crypto, digest1) == -1) { log(LOG_ERR,"Could not set encryption key."); crypto_free_cipher_env(circ->n_crypto); return -1; } if (crypto_cipher_decrypt_init_cipher(circ->n_crypto)) /* crypto_cipher_init_cipher error */ { log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci); EVP_CIPHER_CTX_cleanup(&circ->n_ctx); EVP_CIPHER_CTX_cleanup(&circ->p_ctx); crypto_free_cipher_env(circ->n_crypto); return -1; } log(LOG_DEBUG,"circuit_init(): Cipher initialization complete."); circ->expire = ol->expire; Loading Loading @@ -276,13 +298,12 @@ int circuit_deliver_data_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { char *out; int outlen; int i; crypt_path_t *thishop; assert(circ && in); out = malloc(inlen); out = (char *)malloc(inlen); if(!out) return -1; Loading @@ -298,8 +319,8 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { thishop = circ->cpath[i]; /* encrypt */ if(!EVP_EncryptUpdate(&thishop->f_ctx,out,&outlen,in,inlen)) { log(LOG_ERR,"Error performing encryption:%s",ERR_reason_error_string(ERR_get_error())); if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, (unsigned char *)out)) { log(LOG_ERR,"Error performing encryption:%s",crypto_perror()); free(out); return -1; } Loading @@ -308,9 +329,9 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { memcpy(in,out,inlen); } } else { /* we're in the middle. Just one crypt. */ if(!EVP_EncryptUpdate(&circ->p_ctx,out,&outlen,in,inlen)) { if(crypto_cipher_encrypt(circ->p_crypto,in, inlen, out)) { log(LOG_ERR,"circuit_encrypt(): Encryption failed for ACI : %u (%s).", circ->p_aci, ERR_reason_error_string(ERR_get_error())); circ->p_aci, crypto_perror()); free(out); return -1; } Loading @@ -327,8 +348,8 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { thishop = circ->cpath[i]; /* encrypt */ if(!EVP_DecryptUpdate(&thishop->b_ctx,out,&outlen,in,inlen)) { log(LOG_ERR,"Error performing decryption:%s",ERR_reason_error_string(ERR_get_error())); if(crypto_cipher_decrypt(thishop->b_crypto, in, inlen, out)) { log(LOG_ERR,"Error performing decryption:%s",crypto_perror()); free(out); return -1; } Loading @@ -337,9 +358,9 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { memcpy(in,out,inlen); } } else { /* we're in the middle. Just one crypt. */ if(!EVP_DecryptUpdate(&circ->n_ctx,out,&outlen,in,inlen)) { if(crypto_cipher_decrypt(circ->n_crypto,in, inlen, out)) { log(LOG_ERR,"circuit_crypt(): Decryption failed for ACI : %u (%s).", circ->n_aci, ERR_reason_error_string(ERR_get_error())); circ->n_aci, crypto_perror()); free(out); return -1; } Loading Loading
src/common/Makefile.am +2 −2 Original line number Diff line number Diff line Loading @@ -3,9 +3,9 @@ noinst_LIBRARIES = libor.a #CFLAGS = -Wall -Wpointer-arith -O2 libor_a_SOURCES = config.c key.c log.c utils.c crypto.c libor_a_SOURCES = config.c log.c utils.c crypto.c noinst_HEADERS = config.h key.h log.h \ noinst_HEADERS = config.h log.h \ policies.h utils.h \ ss.h version.h crypto.h
src/common/crypto.c +129 −17 Original line number Diff line number Diff line Loading @@ -2,11 +2,21 @@ /* See LICENSE for licensing information */ /* $Id$ */ #include "crypto.h" #include <string.h> #include <openssl/err.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> #include <openssl/rand.h> #include <stdlib.h> #include <assert.h> #include "crypto.h" #include "config.h" #include "log.h" int crypto_global_init() { ERR_load_crypto_strings(); Loading Loading @@ -201,8 +211,9 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src) switch(env->type) { case CRYPTO_PK_RSA: /* if (env->key) RSA_free((RSA *)env->key); RSA_free((RSA *)env->key);*/ env->key = (unsigned char *)PEM_read_RSAPrivateKey(src, (RSA **)&env->key, NULL, NULL); if (!env->key) return -1; Loading @@ -213,14 +224,60 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src) return 0; } int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile) { FILE *f_pr; int retval = 0; assert(env && keyfile); if (strspn(keyfile,CONFIG_LEGAL_FILENAME_CHARACTERS) == strlen(keyfile)) /* filename contains legal characters only */ { /* open the keyfile */ f_pr=fopen(keyfile,"r"); if (!f_pr) return -1; /* read the private key */ retval = crypto_pk_read_private_key(env, f_pr); fclose(f_pr); if (retval == -1) { log(LOG_ERR,"Error reading private key : %s",crypto_perror()); return -1; } /* check the private key */ retval = crypto_pk_check_key(env); if (retval == 0) { log(LOG_ERR,"Private key read but is invalid : %s.", crypto_perror()); return -1; } else if (retval == -1) { log(LOG_ERR,"Private key read but validity checking failed : %s",crypto_perror()); return -1; } else if (retval == 1) { return 0; } } /* filename contains legal characters only */ return -1; /* report error */ } int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src) { assert(env && src); switch(env->type) { case CRYPTO_PK_RSA: /* if (env->key) RSA_free((RSA *)env->key); RSA_free((RSA *)env->key);*/ env->key = (unsigned char *)PEM_read_RSAPublicKey(src, (RSA **)&env->key, NULL, NULL); if (!env->key) return -1; Loading Loading @@ -285,9 +342,9 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key) switch(env->type) { case CRYPTO_PK_RSA: if (env->key) RSA_free((RSA *)env->key); env->key = key; if (!env->key) return -1; memcpy((void *)env->key, (void *)key, sizeof(RSA)); break; default : return -1; Loading @@ -296,6 +353,36 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key) return 0; } int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) { int result; if (!a || !b) return -1; if (!a->key || !b->key) return -1; if (a->type != b->type) return -1; switch(a->type) { case CRYPTO_PK_RSA: assert(((RSA *)a->key)->n && ((RSA *)a->key)->e && ((RSA *)b->key)->n && ((RSA *)b->key)->e); result = BN_cmp(((RSA *)a->key)->n, ((RSA *)b->key)->n); if (result) return result; return BN_cmp(((RSA *)a->key)->e, ((RSA *)b->key)->e); default: return -1; } } int crypto_pk_keysize(crypto_pk_env_t *env) { assert(env && env->key); return RSA_size((RSA *)env->key); } int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding) { assert(env && from && to); Loading @@ -321,6 +408,23 @@ int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *from, int fro } /* symmetric crypto */ int crypto_cipher_generate_key(crypto_cipher_env_t *env) { assert(env); switch(env->type) { case CRYPTO_CIPHER_IDENTITY: return 0; case CRYPTO_CIPHER_DES: return crypto_rand(8, env->key); case CRYPTO_CIPHER_RC4: return crypto_rand(16, env->key); default: return -1; } } int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv) { assert(env && iv); Loading @@ -329,10 +433,14 @@ int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv) case CRYPTO_CIPHER_IDENTITY: break; case CRYPTO_CIPHER_DES: if (!env->iv) return -1; memcpy((void *)env->iv, (void *)iv, 8); break; case CRYPTO_CIPHER_RC4: if (env->iv) free((void *)env->iv); env->iv = iv; if (!env->iv) return -1; memcpy((void *)env->iv, (void *)iv, 16); break; default: return -1; Loading @@ -348,10 +456,14 @@ int crypto_cipher_set_key(crypto_cipher_env_t *env, unsigned char *key) case CRYPTO_CIPHER_IDENTITY: break; case CRYPTO_CIPHER_DES: if (!env->key) return -1; memcpy((void *)env->key, (void *)key, 8); break; case CRYPTO_CIPHER_RC4: if (env->key) free((void *)env->key); env->key = key; if (!env->key) return -1; memcpy((void *)env->key, (void *)key, 16); break; default: return -1; Loading Loading @@ -396,7 +508,7 @@ int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env) return 0; } int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, size_t fromlen, unsigned char *to) { int tolen; Loading @@ -405,7 +517,7 @@ int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, unsigne return !(EVP_EncryptUpdate((EVP_CIPHER_CTX *)env->aux, to, &tolen, from, fromlen)); } int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *from, size_t fromlen, unsigned char *to) { int tolen; Loading @@ -425,7 +537,7 @@ int crypto_SHA_digest(unsigned char *m, int len, unsigned char *digest) int crypto_rand(unsigned int n, unsigned char *to) { assert(to); return (RAND_bytes(to, n) == -1); return (RAND_bytes(to, n) != 1); } int crypto_pseudo_rand(unsigned int n, unsigned char *to) Loading
src/common/crypto.h +5 −4 Original line number Diff line number Diff line Loading @@ -5,11 +5,8 @@ #ifndef __CRYPTO_H #define __CRYPTO_H #include <openssl/err.h> #include <stdio.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> #include <openssl/rand.h> /* available encryption primitives */ #define CRYPTO_CIPHER_IDENTITY 0 Loading Loading @@ -54,13 +51,17 @@ int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src); int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest); int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest); int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile); int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key); int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b); int crypto_pk_keysize(crypto_pk_env_t *env); int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding); int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding); /* symmetric crypto */ int crypto_cipher_generate_key(crypto_cipher_env_t *env); int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv); int crypto_cipher_set_key(crypto_cipher_env_t *env, unsigned char *key); int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env); Loading
src/or/cell.c +2 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,8 @@ static cell_t *new_create_cell(uint16_t aci, unsigned char length, unsigned char c->seq = 0; memcpy((void *)c->payload, (void *)buf, length); retval = RAND_pseudo_bytes((unsigned char *)(c->payload+length),CELL_PAYLOAD_SIZE-length); if (retval == -1) /* RAND_pseudo_bytes() error */ retval = crypto_pseudo_rand(CELL_PAYLOAD_SIZE-length, (unsigned char *)(c->payload+length)); if (retval) /* RAND_pseudo_bytes() error */ { free((void *)c); return NULL; Loading
src/or/circuit.c +62 −41 Original line number Diff line number Diff line Loading @@ -67,8 +67,10 @@ circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) { void circuit_free(circuit_t *circ) { EVP_CIPHER_CTX_cleanup(&circ->n_ctx); EVP_CIPHER_CTX_cleanup(&circ->p_ctx); if (circ->n_crypto) crypto_free_cipher_env(circ->n_crypto); if (circ->p_crypto) crypto_free_cipher_env(circ->p_crypto); if(circ->onion) free(circ->onion); Loading @@ -93,7 +95,7 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) { log(LOG_DEBUG,"get_unique_aci_by_addr_port() trying to get a unique aci"); RAND_pseudo_bytes((unsigned char *)&test_aci, 2); crypto_pseudo_rand(2, (unsigned char *)&test_aci); if(aci_type == ACI_TYPE_LOWER) test_aci &= htons(0x00FF); Loading @@ -117,7 +119,7 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) { int circuit_init(circuit_t *circ, int aci_type) { onion_layer_t *ol; int retval = 0; unsigned char iv[16]; unsigned char digest1[20]; unsigned char digest2[20]; Loading @@ -143,32 +145,23 @@ int circuit_init(circuit_t *circ, int aci_type) { log(LOG_DEBUG,"circuit_init(): Chosen ACI %u.",circ->n_aci); /* keys */ SHA1(ol->keyseed,16,digest1); SHA1(digest1,20,digest2); SHA1(digest2,20,digest1); memcpy(circ->p_key,digest2,16); memcpy(circ->n_key,digest1,16); memset((void *)iv, 0, 16); crypto_SHA_digest(ol->keyseed,16,digest1); crypto_SHA_digest(digest1,20,digest2); crypto_SHA_digest(digest2,20,digest1); log(LOG_DEBUG,"circuit_init(): Computed keys."); /* set IVs to zero */ memset(circ->n_iv,0,16); memset(circ->p_iv,0,16); /* initialize cipher context */ EVP_CIPHER_CTX_init(&circ->n_ctx); EVP_CIPHER_CTX_init(&circ->p_ctx); /* initialize crypto engines */ switch(circ->p_f) { case ONION_CIPHER_DES : retval = EVP_EncryptInit(&circ->p_ctx, EVP_des_ofb(), circ->p_key, circ->p_iv); circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); break; case ONION_CIPHER_RC4 : retval = EVP_EncryptInit(&circ->p_ctx, EVP_rc4(), circ->p_key,circ->p_iv); circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); break; case ONION_CIPHER_IDENTITY : retval = EVP_EncryptInit(&circ->p_ctx, EVP_enc_null(), circ->p_key, circ->p_iv); circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY); break; default : log(LOG_ERR,"Onion contains unrecognized cipher(%u) for ACI : %u.",circ->p_f,circ->n_aci); Loading @@ -176,36 +169,65 @@ int circuit_init(circuit_t *circ, int aci_type) { break; } if (!retval) /* EVP_EncryptInit() error */ if (!circ->p_crypto) { log(LOG_ERR,"Could not create a cryptographic environment."); return -1; } if (crypto_cipher_set_iv(circ->p_crypto, iv) == -1) { log(LOG_ERR,"Could not set the IV."); crypto_free_cipher_env(circ->p_crypto); return -1; } if (crypto_cipher_set_key(circ->p_crypto, digest2) == -1) { log(LOG_ERR,"Could not set encryption key."); crypto_free_cipher_env(circ->p_crypto); return -1; } if (crypto_cipher_encrypt_init_cipher(circ->p_crypto)) /* crypto_cipher_init_cipher error */ { log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci); EVP_CIPHER_CTX_cleanup(&circ->n_ctx); EVP_CIPHER_CTX_cleanup(&circ->p_ctx); crypto_free_cipher_env(circ->p_crypto); return -1; } switch(circ->n_f) { case ONION_CIPHER_DES : retval = EVP_DecryptInit(&circ->n_ctx, EVP_des_ofb(), circ->n_key, circ->n_iv); circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); break; case ONION_CIPHER_RC4 : retval = EVP_DecryptInit(&circ->n_ctx, EVP_rc4(), circ->n_key,circ->n_iv); circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); break; case ONION_CIPHER_IDENTITY : retval = EVP_DecryptInit(&circ->n_ctx, EVP_enc_null(), circ->n_key, circ->n_iv); circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY); break; default : log(LOG_ERR,"Onion contains unrecognized cipher for ACI : %u.",circ->n_aci); log(LOG_ERR,"Onion contains unrecognized cipher(%u) for ACI : %u.",circ->n_f,circ->n_aci); return -1; break; } if (!retval) /* EVP_EncryptInit() error */ if (!circ->n_crypto) { log(LOG_ERR,"Could not create a cryptographic environment."); return -1; } if (crypto_cipher_set_iv(circ->n_crypto, iv) == -1) { log(LOG_ERR,"Could not set the IV."); crypto_free_cipher_env(circ->n_crypto); return -1; } if (crypto_cipher_set_key(circ->n_crypto, digest1) == -1) { log(LOG_ERR,"Could not set encryption key."); crypto_free_cipher_env(circ->n_crypto); return -1; } if (crypto_cipher_decrypt_init_cipher(circ->n_crypto)) /* crypto_cipher_init_cipher error */ { log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci); EVP_CIPHER_CTX_cleanup(&circ->n_ctx); EVP_CIPHER_CTX_cleanup(&circ->p_ctx); crypto_free_cipher_env(circ->n_crypto); return -1; } log(LOG_DEBUG,"circuit_init(): Cipher initialization complete."); circ->expire = ol->expire; Loading Loading @@ -276,13 +298,12 @@ int circuit_deliver_data_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { char *out; int outlen; int i; crypt_path_t *thishop; assert(circ && in); out = malloc(inlen); out = (char *)malloc(inlen); if(!out) return -1; Loading @@ -298,8 +319,8 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { thishop = circ->cpath[i]; /* encrypt */ if(!EVP_EncryptUpdate(&thishop->f_ctx,out,&outlen,in,inlen)) { log(LOG_ERR,"Error performing encryption:%s",ERR_reason_error_string(ERR_get_error())); if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, (unsigned char *)out)) { log(LOG_ERR,"Error performing encryption:%s",crypto_perror()); free(out); return -1; } Loading @@ -308,9 +329,9 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { memcpy(in,out,inlen); } } else { /* we're in the middle. Just one crypt. */ if(!EVP_EncryptUpdate(&circ->p_ctx,out,&outlen,in,inlen)) { if(crypto_cipher_encrypt(circ->p_crypto,in, inlen, out)) { log(LOG_ERR,"circuit_encrypt(): Encryption failed for ACI : %u (%s).", circ->p_aci, ERR_reason_error_string(ERR_get_error())); circ->p_aci, crypto_perror()); free(out); return -1; } Loading @@ -327,8 +348,8 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { thishop = circ->cpath[i]; /* encrypt */ if(!EVP_DecryptUpdate(&thishop->b_ctx,out,&outlen,in,inlen)) { log(LOG_ERR,"Error performing decryption:%s",ERR_reason_error_string(ERR_get_error())); if(crypto_cipher_decrypt(thishop->b_crypto, in, inlen, out)) { log(LOG_ERR,"Error performing decryption:%s",crypto_perror()); free(out); return -1; } Loading @@ -337,9 +358,9 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { memcpy(in,out,inlen); } } else { /* we're in the middle. Just one crypt. */ if(!EVP_DecryptUpdate(&circ->n_ctx,out,&outlen,in,inlen)) { if(crypto_cipher_decrypt(circ->n_crypto,in, inlen, out)) { log(LOG_ERR,"circuit_crypt(): Decryption failed for ACI : %u (%s).", circ->n_aci, ERR_reason_error_string(ERR_get_error())); circ->n_aci, crypto_perror()); free(out); return -1; } Loading