diff options
author | Nick Mathewson <nickm@torproject.org> | 2002-10-02 20:39:51 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2002-10-02 20:39:51 +0000 |
commit | bef3424bec7ddc67f9d561b1e7f5aa652fb4893f (patch) | |
tree | c16defaeeb93b2daf54bb45e80e5535aa1d85f8b | |
parent | 7032d16e78fab3b651ea538920c528e403267000 (diff) | |
download | tor-bef3424bec7ddc67f9d561b1e7f5aa652fb4893f.tar tor-bef3424bec7ddc67f9d561b1e7f5aa652fb4893f.tar.gz |
Add convenience functions to wrap create and init for symmetric ciphers; clean up error handling in onion.c
svn:r131
-rw-r--r-- | src/common/crypto.c | 44 | ||||
-rw-r--r-- | src/common/crypto.h | 3 | ||||
-rw-r--r-- | src/or/circuit.c | 71 | ||||
-rw-r--r-- | src/or/onion.c | 329 | ||||
-rw-r--r-- | src/or/or.h | 3 |
5 files changed, 144 insertions, 306 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c index bbf3657d0..fec0a78a6 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -98,6 +98,49 @@ void crypto_free_pk_env(crypto_pk_env_t *env) return; } + +/* Create a new crypto_cipher_env_t for a given onion cipher type, key, + * iv, and encryption flag (1=encrypt, 0=decrypt). Return the crypto object + * on success; NULL on failure. + */ +crypto_cipher_env_t * +crypto_create_init_cipher(int cipher_type, char *key, char *iv, int encrypt_mode) +{ + int r; + crypto_cipher_env_t *crypto = NULL; + + if (! (crypto = crypto_new_cipher_env(cipher_type))) { + log(LOG_ERR, "Unable to allocate crypto object"); + return NULL; + } + + if (crypto_cipher_set_key(crypto, key)) { + log(LOG_ERR, "Unable to set key: %s", crypto_perror()); + goto error; + } + + if (crypto_cipher_set_iv(crypto, iv)) { + log(LOG_ERR, "Unable to set iv: %s", crypto_perror()); + goto error; + } + + if (encrypt_mode) + r = crypto_cipher_encrypt_init_cipher(crypto); + else + r = crypto_cipher_decrypt_init_cipher(crypto); + + if (r) { + log(LOG_ERR, "Unabble to initialize cipher: %s", crypto_perror()); + goto error; + } + return crypto; + + error: + if (crypto) + crypto_free_cipher_env(crypto); + return NULL; +} + crypto_cipher_env_t *crypto_new_cipher_env(int type) { crypto_cipher_env_t *env; @@ -650,3 +693,4 @@ char *crypto_perror() { return (char *)ERR_reason_error_string(ERR_get_error()); } + diff --git a/src/common/crypto.h b/src/common/crypto.h index 71a7a3cf4..4912ff50e 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -74,6 +74,9 @@ int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env); int crypto_cipher_encrypt(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, unsigned int fromlen, unsigned char *to); +/* convenience function: wraps crypto_create_crypto_env, set_key, set_iv, and init. */ +crypto_cipher_env_t *crypto_create_init_cipher(int cipher_type, char *key, char *iv, int encrypt_mode); + /* SHA-1 */ int crypto_SHA_digest(unsigned char *m, int len, unsigned char *digest); diff --git a/src/or/circuit.c b/src/or/circuit.c index bc5bd108c..c6e521e2d 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -157,80 +157,13 @@ int circuit_init(circuit_t *circ, int aci_type) { crypto_SHA_digest(digest2,20,digest1); log(LOG_DEBUG,"circuit_init(): Computed keys."); - /* initialize crypto engines */ - switch(circ->p_f) - { - case ONION_CIPHER_DES : - circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); - break; - case ONION_CIPHER_RC4 : - circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); - break; - case ONION_CIPHER_IDENTITY : - 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); - return -1; - break; - } - - 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 */ - { + if (!(circ->p_crypto = create_onion_cipher(circ->p_f,digest2,iv,1))) { log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci); - crypto_free_cipher_env(circ->p_crypto); return -1; } - switch(circ->n_f) - { - case ONION_CIPHER_DES : - circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); - break; - case ONION_CIPHER_RC4 : - circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); - break; - case ONION_CIPHER_IDENTITY : - circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY); - break; - default : - log(LOG_ERR,"Onion contains unrecognized cipher(%u) for ACI : %u.",circ->n_f,circ->n_aci); - return -1; - break; - } - - 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 */ - { + if (!(circ->n_crypto = create_onion_cipher(circ->n_f, digest1, iv, 0))) { log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci); - crypto_free_cipher_env(circ->n_crypto); return -1; } diff --git a/src/or/onion.c b/src/or/onion.c index 0c680f35f..5dcfebe68 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -175,14 +175,32 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *r return route; } +crypto_cipher_env_t * +create_onion_cipher(int cipher_type, char *key, char *iv, int encrypt_mode) +{ + switch (cipher_type) { + case ONION_CIPHER_DES: + cipher_type = CRYPTO_CIPHER_DES; + break; + case ONION_CIPHER_RC4 : + cipher_type = ONION_CIPHER_RC4; + break; + case ONION_CIPHER_IDENTITY : + cipher_type = CRYPTO_CIPHER_IDENTITY; + break; + default: + log(LOG_ERR, "Unknown cipher type %d", cipher_type); + return NULL; + } + return crypto_create_init_cipher(cipher_type, key, iv, encrypt_mode); +} + /* creates a new onion from route, stores it and its length into buf and len respectively */ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int *route, int routelen, int *len, crypt_path_t **cpath) { int i,j; - int retval = 0; onion_layer_t *layer = NULL; crypt_path_t *hop = NULL; - unsigned char *retbuf = NULL; unsigned char *buf; routerinfo_t *router; unsigned char iv[16]; @@ -195,22 +213,19 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int /* allocate memory for the onion */ buf = (unsigned char *)malloc(*len); - if (!buf) - { + if (!buf) { log(LOG_ERR,"Error allocating memory."); return NULL; } log(LOG_DEBUG,"create_onion() : Allocated memory for the onion."); - for (retval=0; retval<routelen;retval++) - { - log(LOG_DEBUG,"create_onion() : %u : %s:%u, %u/%u",routelen-retval,inet_ntoa(*((struct in_addr *)&((rarray[route[retval]])->addr))),(rarray[route[retval]])->or_port,(rarray[route[retval]])->pkey,crypto_pk_keysize((rarray[route[retval]])->pkey)); + for (i=0; i<routelen;i++) { + log(LOG_DEBUG,"create_onion() : %u : %s:%u, %u/%u",routelen-i,inet_ntoa(*((struct in_addr *)&((rarray[route[i]])->addr))),(rarray[route[i]])->or_port,(rarray[route[i]])->pkey,crypto_pk_keysize((rarray[route[i]])->pkey)); } layer = (onion_layer_t *)(buf + *len - 128); /* pointer to innermost layer */ /* create the onion layer by layer, starting with the innermost */ - for (i=0;i<routelen;i++) - { + for (i=0;i<routelen;i++) { router = rarray[route[i]]; log(LOG_DEBUG,"create_onion() : %u",router); @@ -238,23 +253,10 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int /* Expiration Time */ layer->expire = time(NULL) + 3600; /* NOW + 1 hour */ /* Key Seed Material */ - retval = crypto_rand(16, layer->keyseed); - if (retval) /* error */ + if (crypto_rand(16, layer->keyseed)) /* error */ { log(LOG_ERR,"Error generating random data."); - free((void *)buf); - if (cpath) - { - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - - free((void *)cpath[i]); - } - } - return NULL; + goto error; } log(LOG_DEBUG,"create_onion() : Onion layer %u built : %u, %u, %u, %s, %u.",i+1,layer->zero,layer->backf,layer->forwf,inet_ntoa(*((struct in_addr *)&layer->addr)),layer->port); @@ -262,18 +264,9 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int if (cpath) { cpath[i] = (crypt_path_t *)malloc(sizeof(crypt_path_t)); - if (!cpath[i]) - { + if (!cpath[i]) { log(LOG_ERR,"Error allocating memory."); - free((void *)buf); - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - - free((void *)cpath[i]); - } + goto error; } log(LOG_DEBUG,"create_onion() : Building hop %u of crypt path.",i+1); @@ -294,143 +287,35 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int memset((void *)iv,0,16); /* initialize cipher engines */ - switch(layer->forwf) - { - case ONION_CIPHER_DES : - hop->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); - break; - case ONION_CIPHER_RC4 : - hop->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); - break; - case ONION_CIPHER_IDENTITY : - hop->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY); - break; - } - if (!hop->f_crypto) /* cipher initialization failed */ - { + if (! (hop->f_crypto = create_onion_cipher(hop->forwf, hop->digest3, iv, 1))) { + /* cipher initialization failed */ log(LOG_ERR,"Could not create a crypto environment."); - free((void *)buf); - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - free((void *)cpath[i]); - } - return NULL; - } - /* set the key and IV */ - if (crypto_cipher_set_key(hop->f_crypto, hop->digest3) || - crypto_cipher_set_iv(hop->f_crypto, iv)) { - log(LOG_ERR,"Could not initialize the crypto engine."); - free((void *)buf); - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - free((void *)cpath[i]); - } - return NULL; + goto error; } - switch(layer->backf) - { - case ONION_CIPHER_DES : - hop->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES); - break; - case ONION_CIPHER_RC4 : - hop->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4); - break; - case ONION_CIPHER_IDENTITY : - hop->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY); - break; - } - if (!hop->b_crypto) /* cipher initialization failed */ - { + if (! (hop->b_crypto = create_onion_cipher(hop->backf, hop->digest2, iv, 0))) { + /* cipher initialization failed */ log(LOG_ERR,"Could not create a crypto environment."); - free((void *)buf); - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - free((void *)cpath[i]); - } - return NULL; - } - /* set the key and IV */ - if (crypto_cipher_set_key(hop->b_crypto, hop->digest2) || - crypto_cipher_set_iv(hop->b_crypto, iv)) { - log(LOG_ERR,"Could not initialize the crypto engine."); - free((void *)buf); - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - free((void *)cpath[i]); - } - return NULL; - } - - /* initialize */ - if (crypto_cipher_encrypt_init_cipher(hop->f_crypto) || crypto_cipher_decrypt_init_cipher(hop->b_crypto)) { - log(LOG_ERR,"Could not initialize the crypto engine."); - free((void *)buf); - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - free((void *)cpath[i]); - } - return NULL; + goto error; } log(LOG_DEBUG,"create_onion() : Built corresponding crypt path hop."); } /* padding if this is the innermost layer */ - if (!i) - { - retval=crypto_pseudo_rand(100, (unsigned char *)layer + 28); - if (retval) /* error */ - { + if (!i) { + if (crypto_pseudo_rand(100, (unsigned char *)layer + 28)) { /* error */ log(LOG_ERR,"Error generating pseudo-random data."); - free((void *)buf); - if (cpath) - { - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - free((void *)cpath[i]); - } - } - return NULL; + goto error; } log(LOG_DEBUG,"create_onion() : This is the innermost layer. Adding 100 bytes of padding."); } /* encrypt */ - retbuf = encrypt_onion(layer,128+(i*28),router->pkey); - if (!retbuf) - { + + if (! encrypt_onion(layer,128+(i*28),router->pkey)) { log(LOG_ERR,"Error encrypting onion layer."); - free((void *)buf); - if (cpath) - { - for (j=0;j<i;j++) { - if (cpath[i]->f_crypto) - crypto_free_cipher_env(cpath[i]->f_crypto); - if (cpath[i]->b_crypto) - crypto_free_cipher_env(cpath[i]->b_crypto); - free((void *)cpath[i]); - } - } - return NULL; + goto error; } log(LOG_DEBUG,"create_onion() : Encrypted layer."); @@ -439,6 +324,19 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int } return buf; + error: + if (buf) + free((void *)buf); + if (cpath) { + for (j=0;j<i;j++) { + if (cpath[i]->f_crypto) + crypto_free_cipher_env(cpath[i]->f_crypto); + if (cpath[i]->b_crypto) + crypto_free_cipher_env(cpath[i]->b_crypto); + free((void *)cpath[i]); + } + } + return NULL; } /* encrypts 128 bytes of the onion with the specified public key, the rest with @@ -448,9 +346,8 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_ unsigned char *tmpbuf = NULL; /* temporary buffer for crypto operations */ unsigned char digest[20]; /* stores SHA1 output - 160 bits */ unsigned char iv[8]; - int retval = 0; - crypto_cipher_env_t *crypt_env; /* crypto environment */ + crypto_cipher_env_t *crypt_env = NULL; /* crypto environment */ if ( (onion) && (pkey) ) /* valid parameters */ { @@ -470,68 +367,49 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_ if (crypto_SHA_digest(((onion_layer_t *)onion)->keyseed,16,digest)) { log(LOG_ERR,"Error computing SHA1 digest."); - free((void *)tmpbuf); - return NULL; + goto error; } log(LOG_DEBUG,"encrypt_onion() : Computed DES key."); log(LOG_DEBUG,"encrypt_onion() : Trying to RSA encrypt."); /* encrypt 128 bytes with RSA *pkey */ - retval = crypto_pk_public_encrypt(pkey, (unsigned char *)onion, 128, tmpbuf, RSA_NO_PADDING); - if (retval == -1) - { + if (crypto_pk_public_encrypt(pkey, (unsigned char *)onion, 128, tmpbuf, RSA_NO_PADDING) == -1) { log(LOG_ERR,"Error RSA-encrypting data :%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; + goto error; } log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion."); /* now encrypt the rest with DES OFB */ - crypt_env = crypto_new_cipher_env(CRYPTO_CIPHER_DES); + crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 1); if (!crypt_env) { log(LOG_ERR,"Error creating the crypto environment."); - free((void *)tmpbuf); - return NULL; - } - if (crypto_cipher_set_key(crypt_env, digest)) /* error */ - { - log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; - } - if (crypto_cipher_set_iv(crypt_env, iv)) - { - log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; - } - if (crypto_cipher_encrypt_init_cipher(crypt_env)) { - log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; + goto error; } - retval = crypto_cipher_encrypt(crypt_env,(unsigned char *)onion+128, onionlen-128, (unsigned char *)tmpbuf+128); - if (retval) /* error */ - { + if (crypto_cipher_encrypt(crypt_env,(unsigned char *)onion+128, onionlen-128, (unsigned char *)tmpbuf+128)) { /* error */ log(LOG_ERR,"Error performing DES encryption:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; + goto error; } log(LOG_DEBUG,"encrypt_onion() : DES OFB encrypted the rest of the onion."); - - crypto_free_cipher_env(crypt_env); - + /* now copy tmpbuf to onion */ memcpy((void *)onion,(void *)tmpbuf,onionlen); log(LOG_DEBUG,"encrypt_onion() : Copied cipher to original onion buffer."); free((void *)tmpbuf); + crypto_free_cipher_env(crypt_env); return (unsigned char *)onion; } /* valid parameters */ else return NULL; + + error: + if (tmpbuf) + free((void *)tmpbuf); + if (crypt_env) + crypto_free_cipher_env(crypt_env); + return NULL; } /* decrypts the first 128 bytes using RSA and prkey, decrypts the rest with DES OFB with key1 */ @@ -540,87 +418,65 @@ unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_ void *tmpbuf = NULL; /* temporary buffer for crypto operations */ unsigned char digest[20]; /* stores SHA1 output - 160 bits */ unsigned char iv[8]; - int retval = 0; - crypto_cipher_env_t *crypt_env; /* crypto environment */ + crypto_cipher_env_t *crypt_env =NULL; /* crypto environment */ - if ( (onion) && (prkey) ) /* valid parameters */ - { + if ( (onion) && (prkey) ) { /* valid parameters */ memset((void *)iv,0,8); /* allocate space for tmpbuf */ tmpbuf = malloc(onionlen); - if (!tmpbuf) - { + if (!tmpbuf) { log(LOG_ERR,"Could not allocate memory."); return NULL; } log(LOG_DEBUG,"decrypt_onion() : Allocated memory for the temporary buffer."); /* decrypt 128 bytes with RSA *prkey */ - retval = crypto_pk_private_decrypt(prkey, (unsigned char*)onion, 128, (unsigned char *)tmpbuf, RSA_NO_PADDING); - if (retval == -1) + if (crypto_pk_private_decrypt(prkey, (unsigned char*)onion, 128, (unsigned char *)tmpbuf, RSA_NO_PADDING) == -1) { log(LOG_ERR,"Error RSA-decrypting data :%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; + goto error; } log(LOG_DEBUG,"decrypt_onion() : RSA decryption complete."); /* get key1 = SHA1(KeySeed) */ - retval = crypto_SHA_digest(((onion_layer_t *)tmpbuf)->keyseed,16,digest); - if (retval) + if (crypto_SHA_digest(((onion_layer_t *)tmpbuf)->keyseed,16,digest)) { log(LOG_ERR,"Error computing SHA1 digest."); - free((void *)tmpbuf); - return NULL; + goto error; } log(LOG_DEBUG,"decrypt_onion() : Computed DES key."); /* now decrypt the rest with DES OFB */ - crypt_env = crypto_new_cipher_env(CRYPTO_CIPHER_DES); - if (!crypt_env) - { - log(LOG_ERR,"Error creating the crypto environment."); - free((void *)tmpbuf); - return NULL; + crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 0); + if (!crypt_env) { + log(LOG_ERR,"Error creating crypto environment"); + goto error; } - if (crypto_cipher_set_key(crypt_env, digest)) /* error */ - { - log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; - } - if (crypto_cipher_set_iv(crypt_env, iv)) - { - log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; - } - if (crypto_cipher_decrypt_init_cipher(crypt_env)) { - log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; - } - - retval = crypto_cipher_decrypt(crypt_env,(unsigned char *)onion+128, onionlen-128,(unsigned char *)tmpbuf+128); - if (retval) /* error */ - { + + if (crypto_cipher_decrypt(crypt_env,(unsigned char *)onion+128, onionlen-128,(unsigned char *)tmpbuf+128)) { log(LOG_ERR,"Error performing DES decryption:%s",crypto_perror()); - free((void *)tmpbuf); - return NULL; + goto error; } - crypto_free_cipher_env(crypt_env); log(LOG_DEBUG,"decrypt_onion() : DES decryption complete."); /* now copy tmpbuf to onion */ memcpy((void *)onion,(void *)tmpbuf,onionlen); free((void *)tmpbuf); + crypto_free_cipher_env(crypt_env); return (unsigned char *)onion; } /* valid parameters */ else return NULL; + + error: + if (tmpbuf) + free((void *)tmpbuf); + if (crypt_env) + crypto_free_cipher_env(crypt_env); + return NULL; } /* delete first n bytes of the onion and pads the end with n bytes of random data */ @@ -711,4 +567,3 @@ tracked_onion_t *id_tracked_onion(unsigned char *onion, uint32_t onionlen, track return NULL; } - diff --git a/src/or/or.h b/src/or/or.h index 4afd38d7e..b16b00dd9 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -660,6 +660,9 @@ void remove_tracked_onion(tracked_onion_t *to, tracked_onion_t **tracked_onions, /* find a tracked onion in the linked list of tracked onions */ tracked_onion_t *id_tracked_onion(unsigned char *onion, uint32_t onionlen, tracked_onion_t *tracked_onions); +/* create a cipher by onion cipher type. */ +crypto_cipher_env_t *create_onion_cipher(int cipher_type, char *key, char *iv, int encrypt_mode); + /********************************* routers.c ***************************/ void router_retry_connections(struct sockaddr_in *local); |