From 137b577bbd52a2da8f35a6b38514457868460e36 Mon Sep 17 00:00:00 2001
From: Nick Mathewson <nickm@torproject.org>
Date: Sat, 3 Apr 2004 02:40:30 +0000
Subject: Refactor the heck out of crypto interface: admit that we will stick
 with one ciphersuite at a time, make const things const, and stop putting
 openssl in the headers.

svn:r1458
---
 src/common/aes.c     |   6 +-
 src/common/aes.h     |   4 +-
 src/common/crypto.c  | 642 +++++++++++++++++----------------------------------
 src/common/crypto.h  |  86 ++++---
 src/common/log.c     |   2 +
 src/common/tortls.c  |   3 +-
 src/or/circuit.c     |  24 +-
 src/or/onion.c       |  28 ++-
 src/or/or.h          |  15 +-
 src/or/rendcommon.c  |   2 +-
 src/or/rendmid.c     |   2 +-
 src/or/rendservice.c |  16 +-
 src/or/router.c      |   2 +-
 src/or/routerlist.c  |   4 +-
 src/or/test.c        | 165 ++++++-------
 15 files changed, 379 insertions(+), 622 deletions(-)

diff --git a/src/common/aes.c b/src/common/aes.c
index 570173bd7..e4b3c8316 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -67,7 +67,7 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher)
 aes_cnt_cipher_t*
 aes_new_cipher()
 {
-  aes_cnt_cipher_t* result = (aes_cnt_cipher_t*) tor_malloc(sizeof(aes_cnt_cipher_t));
+  aes_cnt_cipher_t* result = tor_malloc(sizeof(aes_cnt_cipher_t));
   memset(result->rk, 0, 4*(MAXNR+1));
   memset(result->buf, 0, 16);
 
@@ -75,7 +75,7 @@ aes_new_cipher()
 }
 
 void
-aes_set_key(aes_cnt_cipher_t *cipher, unsigned char *key, int key_bits)
+aes_set_key(aes_cnt_cipher_t *cipher, const unsigned char *key, int key_bits)
 {
   cipher->nr = rijndaelKeySetupEnc(cipher->rk, key, key_bits);
   cipher->counter0 = 0;
@@ -93,7 +93,7 @@ aes_free_cipher(aes_cnt_cipher_t *cipher)
 }
 
 void
-aes_crypt(aes_cnt_cipher_t *cipher, char *input, int len, char *output)
+aes_crypt(aes_cnt_cipher_t *cipher, const char *input, int len, char *output)
 {
   int c = cipher->pos;
   if (!len) return;
diff --git a/src/common/aes.h b/src/common/aes.h
index 918770889..f162da201 100644
--- a/src/common/aes.h
+++ b/src/common/aes.h
@@ -14,8 +14,8 @@ typedef struct aes_cnt_cipher aes_cnt_cipher_t;
 
 aes_cnt_cipher_t* aes_new_cipher();
 void aes_free_cipher(aes_cnt_cipher_t *cipher);
-void aes_set_key(aes_cnt_cipher_t *cipher, unsigned char *key, int key_bits);
-void aes_crypt(aes_cnt_cipher_t *cipher, char *input, int len, char *output);
+void aes_set_key(aes_cnt_cipher_t *cipher, const unsigned char *key, int key_bits);
+void aes_crypt(aes_cnt_cipher_t *cipher, const char *input, int len, char *output);
 uint64_t aes_get_counter(aes_cnt_cipher_t *cipher);
 void aes_set_counter(aes_cnt_cipher_t *cipher, uint64_t counter);
 void aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta);
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 16f7c18b1..6f1d49d00 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -14,6 +14,8 @@
 #include <openssl/opensslv.h>
 #include <openssl/bn.h>
 #include <openssl/dh.h>
+#include <openssl/rsa.h>
+#include <openssl/dh.h>
 
 #include <stdlib.h>
 #include <assert.h>
@@ -48,79 +50,39 @@
 
 struct crypto_pk_env_t
 {
-  int type;
   int refs; /* reference counting; so we don't have to copy keys */
-  unsigned char *key;
-  /* auxiliary data structure(s) used by the underlying crypto library */
-  unsigned char *aux;
+  RSA *key;
 };
 
 struct crypto_cipher_env_t
 {
-  int type;
-  unsigned char *key;
-  unsigned char *iv;
-  /* auxiliary data structure(s) used by the underlying crypto library */
-  unsigned char *aux;
+  unsigned char key[CIPHER_KEY_LEN];
+  unsigned char iv[CIPHER_IV_LEN];
+  aes_cnt_cipher_t *cipher;
 };
 
-/* static INLINE const EVP_CIPHER *
-   crypto_cipher_evp_cipher(int type, int enc);
-*/
+struct crypto_dh_env_t {
+  DH *dh;
+};
 
 static INLINE int
-crypto_cipher_iv_length(int type) {
-  /*
-  printf("%d -> %d IV\n",type,
-         EVP_CIPHER_iv_length(crypto_cipher_evp_cipher(type,0)));
-  */
-  switch(type)
+crypto_get_rsa_padding_overhead(int padding) {
+  switch(padding)
     {
-    case CRYPTO_CIPHER_IDENTITY: return 0;
-    case CRYPTO_CIPHER_DES: return 8;
-    case CRYPTO_CIPHER_RC4: return 16;
-    case CRYPTO_CIPHER_3DES: return 8;
-    case CRYPTO_CIPHER_AES_CTR: return 0;
+    case RSA_NO_PADDING: return 0;
+    case RSA_PKCS1_OAEP_PADDING: return 42;
+    case RSA_PKCS1_PADDING: return 11;
     default: assert(0); return -1;
     }
 }
 
 static INLINE int
-crypto_cipher_key_length(int type) {
-  /*
-  printf("%d -> %d\n",type,
-         EVP_CIPHER_key_length(crypto_cipher_evp_cipher(type,0)));
-  */
-  switch(type)
-    {
-    case CRYPTO_CIPHER_IDENTITY: return 0;
-    case CRYPTO_CIPHER_DES: return 8;
-    case CRYPTO_CIPHER_RC4: return 16;
-    case CRYPTO_CIPHER_3DES: return 16;
-    case CRYPTO_CIPHER_AES_CTR: return 16;
-    default: assert(0); return -1;
-    }
-}
-
-static INLINE const EVP_CIPHER *
-crypto_cipher_evp_cipher(int type, int enc) {
-  switch(type)
-    {
-    case CRYPTO_CIPHER_IDENTITY: return EVP_enc_null();
-    case CRYPTO_CIPHER_DES: return EVP_des_ofb();
-    case CRYPTO_CIPHER_RC4: return EVP_rc4();
-    case CRYPTO_CIPHER_3DES: return EVP_des_ede_ofb();
-    default: return NULL;
-    }
-}
-
-static INLINE int
-crypto_get_rsa_padding_overhead(int padding) {
+crypto_get_rsa_padding(int padding) {
   switch(padding)
     {
-    case RSA_NO_PADDING: return 0;
-    case RSA_PKCS1_OAEP_PADDING: return 42;
-    case RSA_PKCS1_PADDING: return 11;
+    case PK_NO_PADDING: return RSA_NO_PADDING;
+    case PK_PKCS1_PADDING: return RSA_PKCS1_PADDING;
+    case PK_PKCS1_OAEP_PADDING: return RSA_PKCS1_OAEP_PADDING;
     default: assert(0); return -1;
     }
 }
@@ -142,33 +104,30 @@ int crypto_global_cleanup()
   return 0;
 }
 
+/* used by tortls.c */
 crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa)
 {
   crypto_pk_env_t *env;
   assert(rsa);
-  env = (crypto_pk_env_t *)tor_malloc(sizeof(crypto_pk_env_t));
-  env->type = CRYPTO_PK_RSA;
+  env = tor_malloc(sizeof(crypto_pk_env_t));
   env->refs = 1;
-  env->key = (unsigned char*)rsa;
-  env->aux = NULL;
+  env->key = rsa;
   return env;
 }
 
+/* used by tortls.c */
 RSA *_crypto_pk_env_get_rsa(crypto_pk_env_t *env)
 {
-  if (env->type != CRYPTO_PK_RSA)
-    return NULL;
-  return (RSA*)env->key;
+  return env->key;
 }
 
+/* used by tortls.c */
 EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env)
 {
   RSA *key = NULL;
   EVP_PKEY *pkey = NULL;
-  if (env->type != CRYPTO_PK_RSA)
-    return NULL;
   assert(env->key);
-  if (!(key = RSAPrivateKey_dup((RSA*)env->key)))
+  if (!(key = RSAPrivateKey_dup(env->key)))
     goto error;
   if (!(pkey = EVP_PKEY_new()))
     goto error;
@@ -183,18 +142,18 @@ EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env)
   return NULL;
 }
 
-crypto_pk_env_t *crypto_new_pk_env(int type)
+DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh)
+{
+  return dh->dh;
+}
+
+crypto_pk_env_t *crypto_new_pk_env(void)
 {
   RSA *rsa;
 
-  switch(type) {
-    case CRYPTO_PK_RSA:
-      rsa = RSA_new();
-      if (!rsa) return NULL;
-      return _crypto_new_pk_env_rsa(rsa);
-    default:
-      return NULL;
-  }
+  rsa = RSA_new();
+  if (!rsa) return NULL;
+  return _crypto_new_pk_env_rsa(rsa);
 }
 
 void crypto_free_pk_env(crypto_pk_env_t *env)
@@ -204,14 +163,8 @@ void crypto_free_pk_env(crypto_pk_env_t *env)
   if(--env->refs > 0)
     return;
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      if (env->key)
-        RSA_free((RSA *)env->key);
-      break;
-    default:
-      break;
-  }
+  if (env->key)
+    RSA_free(env->key);
 
   free(env);
 }
@@ -222,12 +175,12 @@ void crypto_free_pk_env(crypto_pk_env_t *env)
  * on success; NULL on failure.
  */
 crypto_cipher_env_t *
-crypto_create_init_cipher(int cipher_type, char *key, char *iv, int encrypt_mode)
+crypto_create_init_cipher(const char *key, const char *iv, int encrypt_mode)
 {
   int r;
   crypto_cipher_env_t *crypto = NULL;
 
-  if (! (crypto = crypto_new_cipher_env(cipher_type))) {
+  if (! (crypto = crypto_new_cipher_env())) {
     log_fn(LOG_WARN, "Unable to allocate crypto object");
     return NULL;
   }
@@ -259,72 +212,22 @@ crypto_create_init_cipher(int cipher_type, char *key, char *iv, int encrypt_mode
   return NULL;
 }
 
-crypto_cipher_env_t *crypto_new_cipher_env(int type)
+crypto_cipher_env_t *crypto_new_cipher_env()
 {
   crypto_cipher_env_t *env;
-  int iv_len, key_len;
-
-  env = (crypto_cipher_env_t *)tor_malloc(sizeof(crypto_cipher_env_t));
-
-  env->type = type;
-  env->key = NULL;
-  env->iv = NULL;
-  env->aux = NULL;
-
-  iv_len = crypto_cipher_iv_length(type);
-  key_len = crypto_cipher_key_length(type);
-
-  if (type == CRYPTO_CIPHER_AES_CTR) {
-    env->aux = (unsigned char *)aes_new_cipher();
-  } else if (! crypto_cipher_evp_cipher(type,0))
-    /* This is not an openssl cipher */
-    goto err;
-  else {
-    env->aux = (unsigned char *)tor_malloc(sizeof(EVP_CIPHER_CTX));
-    EVP_CIPHER_CTX_init((EVP_CIPHER_CTX *)env->aux);
-  }
-
-  if(iv_len)
-    env->iv = (unsigned char *)tor_malloc(iv_len);
-
-  if(key_len)
-    env->key = (unsigned char *)tor_malloc(key_len);
 
+  env = tor_malloc_zero(sizeof(crypto_cipher_env_t));
+  env->cipher = aes_new_cipher();
   return env;
-err:
-  if (env->key)
-    free(env->key);
-  if (env->iv)
-    free(env->iv);
-  if (env->aux)
-    free(env->aux);
-  if (env)
-    free(env);
-  return NULL;
 }
 
 void crypto_free_cipher_env(crypto_cipher_env_t *env)
 {
   assert(env);
 
-  if (env->type == CRYPTO_CIPHER_AES_CTR) {
-    assert(env->aux);
-    aes_free_cipher((aes_cnt_cipher_t*)env->aux);
-    env->aux = NULL;
-  } else if (crypto_cipher_evp_cipher(env->type,0)) {
-    /* This is an openssl cipher */
-    assert(env->aux);
-    EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX *)env->aux);
-  }
-
-  if (env->aux)
-    free((void *)env->aux);
-  if (env->iv)
-    free((void *)env->iv);
-  if (env->key)
-    free((void *)env->key);
-
-  free((void *)env);
+  assert(env->cipher);
+  aes_free_cipher(env->cipher);
+  tor_free(env);
 }
 
 /* public key crypto */
@@ -332,17 +235,11 @@ int crypto_pk_generate_key(crypto_pk_env_t *env)
 {
   assert(env);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-    if (env->key)
-      RSA_free((RSA *)env->key);
-    env->key = (unsigned char *)RSA_generate_key(1024,65537, NULL, NULL);
-    if (!env->key)
-      return -1;
-    break;
-    default:
+  if (env->key)
+    RSA_free(env->key);
+  env->key = RSA_generate_key(PK_BITS,65537, NULL, NULL);
+  if (!env->key)
     return -1;
-  }
 
   return 0;
 }
@@ -351,17 +248,11 @@ int crypto_pk_read_private_key_from_file(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);
-    env->key = (unsigned char *)PEM_read_RSAPrivateKey(src, NULL, NULL, NULL);
-    if (!env->key)
-      return -1;
-    break;
-    default :
+  if (env->key)
+    RSA_free(env->key);
+  env->key = PEM_read_RSAPrivateKey(src, NULL, NULL, NULL);
+  if (!env->key)
     return -1;
-  }
 
   return 0;
 }
@@ -407,17 +298,11 @@ int crypto_pk_read_public_key_from_file(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);
-    env->key = (unsigned char *)PEM_read_RSAPublicKey(src, NULL, NULL, NULL);
-    if (!env->key)
-      return -1;
-    break;
-    default :
+  if(env->key)
+    RSA_free(env->key);
+  env->key = PEM_read_RSAPublicKey(src, NULL, NULL, NULL);
+  if (!env->key)
     return -1;
-  }
 
   return 0;
 }
@@ -428,31 +313,23 @@ int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int
 
   assert(env && env->key && dest);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-
-        b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
-
-        /* Now you can treat b as if it were a file.  Just use the
-         * PEM_*_bio_* functions instead of the non-bio variants.
-         */
-        if(!PEM_write_bio_RSAPublicKey(b, (RSA *)env->key))
-          return -1;
+  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
 
-        BIO_get_mem_ptr(b, &buf);
-        BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
-        BIO_free(b);
+  /* Now you can treat b as if it were a file.  Just use the
+   * PEM_*_bio_* functions instead of the non-bio variants.
+   */
+  if(!PEM_write_bio_RSAPublicKey(b, env->key))
+    return -1;
 
-        *dest = tor_malloc(buf->length+1);
-        memcpy(*dest, buf->data, buf->length);
-        (*dest)[buf->length] = 0; /* null terminate it */
-        *len = buf->length;
-        BUF_MEM_free(buf);
+  BIO_get_mem_ptr(b, &buf);
+  BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
+  BIO_free(b);
 
-      break;
-    default:
-      return -1;
-  }
+  *dest = tor_malloc(buf->length+1);
+  memcpy(*dest, buf->data, buf->length);
+  (*dest)[buf->length] = 0; /* null terminate it */
+  *len = buf->length;
+  BUF_MEM_free(buf);
 
   return 0;
 }
@@ -462,22 +339,15 @@ int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src,
 
   assert(env && src);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
+  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
 
-      BIO_write(b, src, len);
+  BIO_write(b, src, len);
 
-      RSA_free((RSA *)env->key);
-      env->key = (unsigned char *)PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
-      if(!env->key)
-        return -1;
-
-      BIO_free(b);
-      break;
-    default:
-      return -1;
-  }
+  if (env->key)
+    RSA_free(env->key);
+  env->key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
+  if(!env->key)
+    return -1;
 
   return 0;
 }
@@ -491,10 +361,10 @@ crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env,
   long len;
   char *s;
   int r;
-  assert(env->type == CRYPTO_PK_RSA);
+
   if (!(bio = BIO_new(BIO_s_mem())))
     return -1;
-  if (PEM_write_bio_RSAPrivateKey(bio, (RSA*)env->key, NULL,NULL,0,NULL,NULL)
+  if (PEM_write_bio_RSAPrivateKey(bio, env->key, NULL,NULL,0,NULL,NULL)
       == 0) {
     BIO_free(bio);
     return -1;
@@ -513,16 +383,10 @@ int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest)
 {
   assert(env && dest);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      if (!env->key)
-        return -1;
-      if (PEM_write_RSAPrivateKey(dest, (RSA *)env->key, NULL, NULL, 0,0, NULL) == 0)
-        return -1;
-      break;
-    default :
-      return -1;
-  }
+  if (!env->key)
+    return -1;
+  if (PEM_write_RSAPrivateKey(dest, env->key, NULL, NULL, 0,0, NULL) == 0)
+    return -1;
 
   return 0;
 }
@@ -530,16 +394,10 @@ int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest)
 {
   assert(env && dest);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      if (!env->key)
-        return -1;
-      if (PEM_write_RSAPublicKey(dest, (RSA *)env->key) == 0)
-        return -1;
-      break;
-    default :
-      return -1;
-  }
+  if (!env->key)
+    return -1;
+  if (PEM_write_RSAPublicKey(dest, env->key) == 0)
+    return -1;
 
   return 0;
 }
@@ -548,12 +406,7 @@ int crypto_pk_check_key(crypto_pk_env_t *env)
 {
   assert(env);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      return RSA_check_key((RSA *)env->key);
-    default:
-      return -1;
-  }
+  return RSA_check_key(env->key);
 }
 
 int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) {
@@ -565,19 +418,11 @@ int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) {
   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;
-  }
+  assert((a->key)->n && (a->key)->e && (b->key)->n && (b->key)->e);
+  result = BN_cmp((a->key)->n, (b->key)->n);
+  if (result)
+    return result;
+  return BN_cmp((a->key)->e, (b->key)->e);
 }
 
 /* return the size of the public key modulus in 'env', in bytes. */
@@ -585,97 +430,71 @@ int crypto_pk_keysize(crypto_pk_env_t *env)
 {
   assert(env && env->key);
 
-  return RSA_size((RSA *)env->key);
+  return RSA_size(env->key);
 }
 
 crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) {
   assert(env && env->key);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      env->refs++;
-      break;
-    default:
-      return NULL;
-  }
-
+  env->refs++;
   return env;
 }
 
-int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding)
+int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding)
 {
   assert(env && from && to);
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      return RSA_public_encrypt(fromlen, from, to, (RSA *)env->key, padding);
-    default:
-      return -1;
-  }
+  return RSA_public_encrypt(fromlen, from, to, env->key,
+                            crypto_get_rsa_padding(padding));
 }
 
-int crypto_pk_private_decrypt(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, const unsigned char *from, int fromlen, unsigned char *to, int padding)
 {
-  assert(env && from && to);
+  assert(env && from && to && env->key);
+  if (!env->key->p)
+    /* Not a private key */
+    return -1;
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      if (!(((RSA*)env->key)->p))
-        return -1;
-      return RSA_private_decrypt(fromlen, from, to, (RSA *)env->key, padding);
-    default:
-      return -1;
-  }
+  return RSA_private_decrypt(fromlen, from, to, env->key,
+                             crypto_get_rsa_padding(padding));
 }
 
-int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to)
+int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to)
 {
   assert(env && from && to);
-
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      return RSA_public_decrypt(fromlen, from, to, (RSA *)env->key,
-                                RSA_PKCS1_PADDING);
-    default:
-      return -1;
-  }
+  return RSA_public_decrypt(fromlen, from, to, env->key, RSA_PKCS1_PADDING);
 }
 
-int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to)
+int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to)
 {
   assert(env && from && to);
+  if (!env->key->p)
+    /* Not a private key */
+    return -1;
 
-  switch(env->type) {
-    case CRYPTO_PK_RSA:
-      if (!(((RSA*)env->key)->p))
-        return -1;
-      return RSA_private_encrypt(fromlen, from, to, (RSA *)env->key,
-                                 RSA_PKCS1_PADDING);
-    default:
-      return -1;
-  }
+  return RSA_private_encrypt(fromlen, from, to, env->key, RSA_PKCS1_PADDING);
 }
 
 /* Return 0 if sig is a correct signature for SHA1(data).  Else return -1.
  */
-int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, unsigned char *data, int datalen, unsigned char *sig, int siglen)
+int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, unsigned char *sig, int siglen)
 {
-  char digest[CRYPTO_SHA1_DIGEST_LEN];
-  char buf[1024];
+  char digest[DIGEST_LEN];
+  char buf[PK_BYTES+1];
   int r;
 
   assert(env && data && sig);
 
-  if (crypto_SHA_digest(data,datalen,digest)<0) {
+  if (crypto_digest(data,datalen,digest)<0) {
     log_fn(LOG_WARN, "couldn't compute digest");
     return -1;
   }
   r = crypto_pk_public_checksig(env,sig,siglen,buf);
-  if (r != CRYPTO_SHA1_DIGEST_LEN) {
+  if (r != DIGEST_LEN) {
     log_fn(LOG_WARN, "Invalid signature");
     return -1;
   }
-  if (memcmp(buf, digest, CRYPTO_SHA1_DIGEST_LEN)) {
+  if (memcmp(buf, digest, DIGEST_LEN)) {
     log_fn(LOG_WARN, "Signature mismatched with digest.");
     return -1;
   }
@@ -685,12 +504,12 @@ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, unsigned char *data,
 
 /* Fill 'to' with a signature of SHA1(from).
  */
-int crypto_pk_private_sign_digest(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to)
+int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to)
 {
-  char digest[CRYPTO_SHA1_DIGEST_LEN];
-  if (crypto_SHA_digest(from,fromlen,digest)<0)
+  char digest[DIGEST_LEN];
+  if (crypto_digest(from,fromlen,digest)<0)
     return 0;
-  return crypto_pk_private_sign(env,digest,CRYPTO_SHA1_DIGEST_LEN,to);
+  return crypto_pk_private_sign(env,digest,DIGEST_LEN,to);
 }
 
 
@@ -711,68 +530,70 @@ int crypto_pk_private_sign_digest(crypto_pk_env_t *env, unsigned char *from, int
  *   padded and encrypted with the public key; followed by the rest of
  *   the source data encrypted in AES-CTR mode with the symmetric key.
  */
-int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, unsigned char *from,
-				    int fromlen, unsigned char *to,
-				    int padding)
+int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
+                                    const unsigned char *from,
+                                    int fromlen, unsigned char *to,
+                                    int padding)
 {
   int overhead, pkeylen, outlen, r, symlen;
   crypto_cipher_env_t *cipher = NULL;
-  char buf[1024];
+  char buf[PK_BYTES+1];
 
   assert(env && from && to);
 
-  overhead = crypto_get_rsa_padding_overhead(padding);
+  overhead = crypto_get_rsa_padding_overhead(crypto_get_rsa_padding(padding));
   pkeylen = crypto_pk_keysize(env);
 
-  if (padding == RSA_NO_PADDING && fromlen < pkeylen)
+  if (padding == PK_NO_PADDING && fromlen < pkeylen)
     return -1;
 
   if (fromlen+overhead <= pkeylen) {
     /* It all fits in a single encrypt. */
     return crypto_pk_public_encrypt(env,from,fromlen,to,padding);
   }
-  cipher = crypto_new_cipher_env(CRYPTO_CIPHER_AES_CTR);
+  cipher = crypto_new_cipher_env();
   if (!cipher) return -1;
   if (crypto_cipher_generate_key(cipher)<0)
     goto err;
-  if (padding == RSA_NO_PADDING)
+  if (padding == PK_NO_PADDING)
     cipher->key[0] &= 0x7f;
   if (crypto_cipher_encrypt_init_cipher(cipher)<0)
     goto err;
-  memcpy(buf, cipher->key, 16);
-  memcpy(buf+16, from, pkeylen-overhead-16);
+  memcpy(buf, cipher->key, CIPHER_KEY_LEN);
+  memcpy(buf+CIPHER_KEY_LEN, from, pkeylen-overhead-CIPHER_KEY_LEN);
 
   /* Length of symmetrically encrypted data. */
-  symlen = fromlen-(pkeylen-overhead-16);
+  symlen = fromlen-(pkeylen-overhead-CIPHER_KEY_LEN);
 
   outlen = crypto_pk_public_encrypt(env,buf,pkeylen-overhead,to,padding);
   if (outlen!=pkeylen) {
     goto err;
   }
   r = crypto_cipher_encrypt(cipher,
-			    from+pkeylen-overhead-16, symlen,
-			    to+outlen);
+                            from+pkeylen-overhead-CIPHER_KEY_LEN, symlen,
+                            to+outlen);
 
   if (r<0) goto err;
-  memset(buf, 0, 1024);
+  memset(buf, 0, sizeof(buf));
   crypto_free_cipher_env(cipher);
   return outlen + symlen;
  err:
-  memset(buf, 0, 1024);
+  memset(buf, 0, sizeof(buf));
   if (cipher) crypto_free_cipher_env(cipher);
   return -1;
 }
 
 /* Invert crypto_pk_public_hybrid_encrypt. */
-int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, unsigned char *from,
-				    int fromlen, unsigned char *to,
-				    int padding)
+int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
+                                     const unsigned char *from,
+                                     int fromlen, unsigned char *to,
+                                     int padding)
 {
   int overhead, pkeylen, outlen, r;
   crypto_cipher_env_t *cipher = NULL;
-  char buf[1024];
+  char buf[PK_BYTES+1];
 
-  overhead = crypto_get_rsa_padding_overhead(padding);
+  overhead = crypto_get_rsa_padding_overhead(crypto_get_rsa_padding(padding));
   pkeylen = crypto_pk_keysize(env);
 
   if (fromlen <= pkeylen) {
@@ -783,25 +604,25 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, unsigned char *from,
     log_fn(LOG_WARN, "Error decrypting public-key data");
     return -1;
   }
-  if (outlen < 16) {
+  if (outlen < CIPHER_KEY_LEN) {
     log_fn(LOG_WARN, "No room for a symmetric key");
     return -1;
   }
-  cipher = crypto_create_init_cipher(CRYPTO_CIPHER_AES_CTR, buf, "", 0);
+  cipher = crypto_create_init_cipher(buf, NULL, 0);
   if (!cipher) {
     return -1;
   }
-  memcpy(to,buf+16,outlen-16);
-  outlen -= 16;
+  memcpy(to,buf+CIPHER_KEY_LEN,outlen-CIPHER_KEY_LEN);
+  outlen -= CIPHER_KEY_LEN;
   r = crypto_cipher_decrypt(cipher, from+pkeylen, fromlen-pkeylen,
-			    to+outlen);
+                            to+outlen);
   if (r<0)
     goto err;
-  memset(buf,0,1024);
+  memset(buf,0,sizeof(buf));
   crypto_free_cipher_env(cipher);
   return outlen + (fromlen-pkeylen);
  err:
-  memset(buf, 0, 1024);
+  memset(buf,0,sizeof(buf));
   if (cipher) crypto_free_cipher_env(cipher);
   return -1;
 }
@@ -813,11 +634,11 @@ int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len)
 {
   int len;
   unsigned char *buf, *bufp;
-  len = i2d_RSAPublicKey((RSA*)pk->key, NULL);
+  len = i2d_RSAPublicKey(pk->key, NULL);
   if (len < 0 || len > dest_len)
     return -1;
-  bufp = buf = (unsigned char *)tor_malloc(len+1);
-  len = i2d_RSAPublicKey((RSA*)pk->key, &bufp);
+  bufp = buf = tor_malloc(len+1);
+  len = i2d_RSAPublicKey(pk->key, &bufp);
   if (len < 0) {
     tor_free(buf);
     return -1;
@@ -854,23 +675,23 @@ crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len)
 }
 
 /* Given a private or public key pk, put a SHA1 hash of the public key into
- * digest_out (must have 20 bytes of space).
+ * digest_out (must have DIGEST_LEN bytes of space).
  */
 int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out)
 {
   unsigned char *buf, *bufp;
   int len;
-  assert(pk->type == CRYPTO_PK_RSA);
-  len = i2d_RSAPublicKey((RSA*)pk->key, NULL);
+
+  len = i2d_RSAPublicKey(pk->key, NULL);
   if (len < 0)
     return -1;
   buf = bufp = tor_malloc(len+1);
-  len = i2d_RSAPublicKey((RSA*)pk->key, &bufp);
+  len = i2d_RSAPublicKey(pk->key, &bufp);
   if (len < 0) {
     free(buf);
     return -1;
   }
-  if (crypto_SHA_digest(buf, len, digest_out) < 0) {
+  if (crypto_digest(buf, len, digest_out) < 0) {
     free(buf);
     return -1;
   }
@@ -885,14 +706,14 @@ int
 crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out)
 {
   unsigned char *bufp;
-  unsigned char digest[20];
+  unsigned char digest[DIGEST_LEN];
   unsigned char buf[FINGERPRINT_LEN+1];
   int i;
   if (crypto_pk_get_digest(pk, digest)) {
     return -1;
   }
   bufp = buf;
-  for (i = 0; i < 20; ++i) {
+  for (i = 0; i < DIGEST_LEN; ++i) {
     sprintf(bufp,"%02X",digest[i]);
     bufp += 2;
     if (i%2 && i != 19) {
@@ -924,54 +745,39 @@ crypto_pk_check_fingerprint_syntax(const char *s)
 /* symmetric crypto */
 int crypto_cipher_generate_key(crypto_cipher_env_t *env)
 {
-  int key_len;
   assert(env);
 
-  key_len = crypto_cipher_key_length(env->type);
-
-  if (key_len > 0)
-    return crypto_rand(key_len, env->key);
-  else if (key_len == 0)
-    return 0;
-  else
-    return -1;
+  return crypto_rand(CIPHER_KEY_LEN, env->key);
 }
 
-int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv)
+int crypto_cipher_set_iv(crypto_cipher_env_t *env, const unsigned char *iv)
 {
-  int iv_len;
-  assert(env && iv);
+  assert(env && (CIPHER_IV_LEN==0 || iv));
 
-  iv_len = crypto_cipher_iv_length(env->type);
-  if (!iv_len)
+  if (!CIPHER_IV_LEN)
     return 0;
 
   if (!env->iv)
     return -1;
 
-  memcpy((void*)env->iv, (void*)iv, iv_len);
+  memcpy(env->iv, iv, CIPHER_IV_LEN);
 
   return 0;
 }
 
-int crypto_cipher_set_key(crypto_cipher_env_t *env, unsigned char *key)
+int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key)
 {
-  int key_len;
   assert(env && key);
 
-  key_len = crypto_cipher_key_length(env->type);
-  if (!key_len)
-    return 0;
-
   if (!env->key)
     return -1;
 
-  memcpy((void*)env->key, (void*)key, key_len);
+  memcpy(env->key, key, CIPHER_KEY_LEN);
 
   return 0;
 }
 
-unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env)
+const unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env)
 {
   return env->key;
 }
@@ -980,60 +786,32 @@ int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env)
 {
   assert(env);
 
-  if (crypto_cipher_evp_cipher(env->type, 1)) {
-    RETURN_SSL_OUTCOME(EVP_EncryptInit((EVP_CIPHER_CTX *)env->aux,
-                                       crypto_cipher_evp_cipher(env->type, 1),
-                                       env->key, env->iv));
-  } else if (env->type == CRYPTO_CIPHER_AES_CTR) {
-    aes_set_key((aes_cnt_cipher_t*)env->aux, env->key, 128);
-    return 0;
-  } else {
-    return -1;
-  }
+  aes_set_key(env->cipher, env->key, CIPHER_KEY_LEN*8);
+  return 0;
 }
 
 int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env)
 {
   assert(env);
 
-  if (crypto_cipher_evp_cipher(env->type, 0)) {
-    RETURN_SSL_OUTCOME(EVP_EncryptInit((EVP_CIPHER_CTX *)env->aux,
-                                       crypto_cipher_evp_cipher(env->type, 0),
-                                       env->key, env->iv));
-  } else if (env->type == CRYPTO_CIPHER_AES_CTR) {
-    aes_set_key((aes_cnt_cipher_t*)env->aux, env->key, 128);
-    return 0;
-  } else {
-    return -1;
-  }
+  aes_set_key(env->cipher, env->key, CIPHER_KEY_LEN*8);
+  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, const unsigned char *from, unsigned int fromlen, unsigned char *to)
 {
-  int tolen;
-
-  assert(env && from && to);
+  assert(env && env->cipher && from && fromlen && to);
 
-  if (env->type == CRYPTO_CIPHER_AES_CTR) {
-    aes_crypt((aes_cnt_cipher_t*)env->aux, from, fromlen, to);
-    return 0;
-  } else {
-    RETURN_SSL_OUTCOME(EVP_EncryptUpdate((EVP_CIPHER_CTX *)env->aux, to, &tolen, from, fromlen));
-  }
+  aes_crypt(env->cipher, from, fromlen, to);
+  return 0;
 }
 
-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, const unsigned char *from, unsigned int fromlen, unsigned char *to)
 {
-  int tolen;
-
   assert(env && from && to);
 
-  if (env->type == CRYPTO_CIPHER_AES_CTR) {
-    aes_crypt((aes_cnt_cipher_t*)env->aux, from, fromlen, to);
-    return 0;
-  } else {
-    RETURN_SSL_OUTCOME(EVP_DecryptUpdate((EVP_CIPHER_CTX *)env->aux, to, &tolen, from, fromlen));
-  }
+  aes_crypt(env->cipher, from, fromlen, to);
+  return 0;
 }
 
 int
@@ -1045,16 +823,12 @@ crypto_cipher_rewind(crypto_cipher_env_t *env, long delta)
 int
 crypto_cipher_advance(crypto_cipher_env_t *env, long delta)
 {
-  if (env->type == CRYPTO_CIPHER_AES_CTR) {
-    aes_adjust_counter((aes_cnt_cipher_t*)env->aux, delta);
-    return 0;
-  } else {
-    return -1;
-  }
+  aes_adjust_counter(env->cipher, delta);
+  return 0;
 }
 
 /* SHA-1 */
-int crypto_SHA_digest(const unsigned char *m, int len, unsigned char *digest)
+int crypto_digest(const unsigned char *m, int len, unsigned char *digest)
 {
   assert(m && digest);
   return (SHA1(m,len,digest) == NULL);
@@ -1065,10 +839,9 @@ struct crypto_digest_env_t {
 };
 
 crypto_digest_env_t *
-crypto_new_digest_env(int type)
+crypto_new_digest_env(void)
 {
   crypto_digest_env_t *r;
-  assert(type == CRYPTO_SHA1_DIGEST);
   r = tor_malloc(sizeof(crypto_digest_env_t));
   SHA1_Init(&r->d);
   return r;
@@ -1076,8 +849,7 @@ crypto_new_digest_env(int type)
 
 void
 crypto_free_digest_env(crypto_digest_env_t *digest) {
-  if(digest)
-    free(digest);
+  tor_free(digest);
 }
 
 void
@@ -1092,9 +864,9 @@ crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
 void crypto_digest_get_digest(crypto_digest_env_t *digest,
                               char *out, size_t out_len)
 {
-  static char r[SHA_DIGEST_LENGTH];
+  static char r[DIGEST_LEN];
   assert(digest && out);
-  assert(out_len <= SHA_DIGEST_LENGTH);
+  assert(out_len <= DIGEST_LEN);
   SHA1_Final(r, &digest->d);
   memcpy(out, r, out_len);
 }
@@ -1225,27 +997,27 @@ int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, int pubkey_len)
 #undef MIN
 #define MIN(a,b) ((a)<(b)?(a):(b))
 int crypto_dh_compute_secret(crypto_dh_env_t *dh,
-                             char *pubkey, int pubkey_len,
+                             const char *pubkey, int pubkey_len,
                              char *secret_out, int secret_bytes_out)
 {
-  unsigned char hash[20];
+  unsigned char hash[DIGEST_LEN];
   unsigned char *secret_tmp = NULL;
   BIGNUM *pubkey_bn = NULL;
   int secret_len;
   int i;
   assert(dh);
-  assert(secret_bytes_out/20 <= 255);
+  assert(secret_bytes_out/DIGEST_LEN <= 255);
 
   if (!(pubkey_bn = BN_bin2bn(pubkey, pubkey_len, NULL)))
     goto error;
   secret_tmp = tor_malloc(crypto_dh_get_bytes(dh)+1);
   secret_len = DH_compute_key(secret_tmp, pubkey_bn, dh->dh);
   /* sometimes secret_len might be less than 128, e.g., 127. that's ok. */
-  for (i = 0; i < secret_bytes_out; i += 20) {
-    secret_tmp[secret_len] = (unsigned char) i/20;
-    if (crypto_SHA_digest(secret_tmp, secret_len+1, hash))
+  for (i = 0; i < secret_bytes_out; i += DIGEST_LEN) {
+    secret_tmp[secret_len] = (unsigned char) i/DIGEST_LEN;
+    if (crypto_digest(secret_tmp, secret_len+1, hash))
       goto error;
-    memcpy(secret_out+i, hash, MIN(20, secret_bytes_out-i));
+    memcpy(secret_out+i, hash, MIN(DIGEST_LEN, secret_bytes_out-i));
   }
   secret_len = secret_bytes_out;
 
@@ -1271,7 +1043,7 @@ int crypto_seed_rng()
 {
   static int provider_set = 0;
   static HCRYPTPROV provider;
-  char buf[21];
+  char buf[DIGEST_LEN+1];
 
   if (!provider_set) {
     if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, 0)) {
@@ -1288,11 +1060,11 @@ int crypto_seed_rng()
     }
     provider_set = 1;
   }
-  if (!CryptGenRandom(provider, 20, buf)) {
+  if (!CryptGenRandom(provider, DIGEST_LEN, buf)) {
     log_fn(LOG_ERR,"Can't get entropy from CryptoAPI.");
     return -1;
   }
-  RAND_seed(buf, 20);
+  RAND_seed(buf, DIGEST_LEN);
   /* And add the current screen state to the entopy pool for
    * good measure. */
   RAND_screen();
@@ -1305,20 +1077,20 @@ int crypto_seed_rng()
     "/dev/srandom", "/dev/urandom", "/dev/random", NULL
   };
   int i, n;
-  char buf[21];
+  char buf[DIGEST_LEN+1];
   FILE *f;
 
   for (i = 0; filenames[i]; ++i) {
     f = fopen(filenames[i], "rb");
     if (!f) continue;
     log_fn(LOG_INFO, "Seeding RNG from %s", filenames[i]);
-    n = fread(buf, 1, 20, f);
+    n = fread(buf, 1, DIGEST_LEN, f);
     fclose(f);
-    if (n != 20) {
+    if (n != DIGEST_LEN) {
       log_fn(LOG_WARN, "Error reading from entropy source");
       return -1;
     }
-    RAND_seed(buf, 20);
+    RAND_seed(buf, DIGEST_LEN);
     return 0;
   }
 
@@ -1362,9 +1134,9 @@ int crypto_pseudo_rand_int(unsigned int max) {
 }
 
 /* errors */
-char *crypto_perror()
+const char *crypto_perror()
 {
-  return (char *)ERR_reason_error_string(ERR_get_error());
+  return (const char *)ERR_reason_error_string(ERR_get_error());
 }
 
 int
@@ -1427,3 +1199,11 @@ base32_encode(char *dest, int destlen, const char *src, int srclen)
   dest[i] = '\0';
   return 0;
 }
+
+/*
+  Local Variables:
+  mode:c
+  indent-tabs-mode:nil
+  c-basic-offset:2
+  End:
+*/
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 970be675c..df349d7e8 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -6,35 +6,32 @@
 #define __CRYPTO_H
 
 #include <stdio.h>
-#include <openssl/rsa.h>
-#include <openssl/dh.h>
 
-/* available encryption primitives */
-#define CRYPTO_CIPHER_IDENTITY 0
-#define CRYPTO_CIPHER_DES 1
-#define CRYPTO_CIPHER_RC4 2
-#define CRYPTO_CIPHER_3DES 3
-#define CRYPTO_CIPHER_AES_CTR 4
-
-#define CRYPTO_PK_RSA 0
-
-#define CRYPTO_SHA1_DIGEST 0
+#define DIGEST_LEN 20
+#define CIPHER_KEY_LEN 16
+#define CIPHER_IV_LEN 0
+#define PK_BITS 1024
+#define PK_BYTES (PK_BITS/8)
+#define CRYPTO_DH_SIZE (1024 / 8)
 
-#define CRYPTO_SHA1_DIGEST_LEN 20
+#define PK_NO_PADDING         60000
+#define PK_PKCS1_PADDING      60001
+#define PK_PKCS1_OAEP_PADDING 60002
 
 typedef struct crypto_pk_env_t crypto_pk_env_t;
 typedef struct crypto_cipher_env_t crypto_cipher_env_t;
 typedef struct crypto_digest_env_t crypto_digest_env_t;
+typedef struct crypto_dh_env_t crypto_dh_env_t;
 
 /* global state */
 int crypto_global_init();
 int crypto_global_cleanup();
 
 /* environment setup */
-crypto_pk_env_t *crypto_new_pk_env(int type);
+crypto_pk_env_t *crypto_new_pk_env(void);
 void crypto_free_pk_env(crypto_pk_env_t *env);
 
-crypto_cipher_env_t *crypto_new_cipher_env(int type);
+crypto_cipher_env_t *crypto_new_cipher_env(void);
 void crypto_free_cipher_env(crypto_cipher_env_t *env);
 
 /* public key crypto */
@@ -50,23 +47,22 @@ int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest);
 int crypto_pk_check_key(crypto_pk_env_t *env);
 int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const 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);
 crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig);
 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);
-int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to);
-int crypto_pk_private_sign_digest(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to);
-int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to);
-int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, unsigned char *data, int datalen, unsigned char *sig, int siglen);
-int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, unsigned char *from,
-				    int fromlen, unsigned char *to,
-				    int padding);
-int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, unsigned char *from,
-				    int fromlen, unsigned char *to,
-				    int padding);
+int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding);
+int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding);
+int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
+int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
+int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to);
+int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, unsigned char *sig, int siglen);
+int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
+                                    const unsigned char *from, int fromlen,
+                                    unsigned char *to, int padding);
+int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
+                                     const unsigned char *from, int fromlen,
+                                     unsigned char *to,int padding);
 
 #define FINGERPRINT_LEN 49
 int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len);
@@ -81,43 +77,37 @@ int base64_decode(char *dest, int destlen, const char *src, int srclen);
 int base32_encode(char *dest, int destlen, const char *src, int srclen);
 
 /* Key negotiation */
-typedef struct crypto_dh_env_st {
-  DH *dh;
-} crypto_dh_env_t;
-
-/* #define CRYPTO_DH_SIZE (1536 / 8) */
-#define CRYPTO_DH_SIZE (1024 / 8)
 crypto_dh_env_t *crypto_dh_new();
 int crypto_dh_get_bytes(crypto_dh_env_t *dh);
 int crypto_dh_generate_public(crypto_dh_env_t *dh);
 int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out,
                          int pubkey_out_len);
 int crypto_dh_compute_secret(crypto_dh_env_t *dh,
-                             char *pubkey, int pubkey_len,
+                             const char *pubkey, int pubkey_len,
                              char *secret_out, int secret_out_len);
 void crypto_dh_free(crypto_dh_env_t *dh);
 
 /* 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_set_iv(crypto_cipher_env_t *env, const unsigned char *iv);
+int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key);
 int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env);
 int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env);
-unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env);
+const unsigned char *crypto_cipher_get_key(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);
+int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to);
+int crypto_cipher_decrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to);
 
 /* only implemented for CRYPTO_CIPHER_AES_CTR */
 int crypto_cipher_rewind(crypto_cipher_env_t *env, long delta);
 int crypto_cipher_advance(crypto_cipher_env_t *env, long delta);
 
 /* 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);
+crypto_cipher_env_t *crypto_create_init_cipher(const char *key, const char *iv, int encrypt_mode);
 
 /* SHA-1 */
-int crypto_SHA_digest(const unsigned char *m, int len, unsigned char *digest);
-crypto_digest_env_t *crypto_new_digest_env(int type);
+int crypto_digest(const unsigned char *m, int len, unsigned char *digest);
+crypto_digest_env_t *crypto_new_digest_env();
 void crypto_free_digest_env(crypto_digest_env_t *digest);
 void crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
                              size_t len);
@@ -134,5 +124,13 @@ void crypto_pseudo_rand(unsigned int n, unsigned char *to);
 int crypto_pseudo_rand_int(unsigned int max);
 
 /* errors */
-char *crypto_perror();
+const char *crypto_perror();
 #endif
+
+/*
+  Local Variables:
+  mode:c
+  indent-tabs-mode:nil
+  c-basic-offset:2
+  End:
+*/
diff --git a/src/common/log.c b/src/common/log.c
index 681e08f12..4245fca5c 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -3,6 +3,8 @@
 /* $Id$ */
 
 #include "../or/or.h"
+#include <stdarg.h>
+
 #ifdef MS_WINDOWS
 #define vsnprintf _vsnprintf
 #endif
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 1531ea211..b3957b857 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -55,6 +55,7 @@ static int tls_library_is_initialized = 0;
 /* These functions are declared in crypto.c but not exported. */
 EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env);
 crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa);
+DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh);
 
 static void
 tls_log_errors(int severity, const char *doing)
@@ -261,7 +262,7 @@ tor_tls_context_new(crypto_pk_env_t *rsa,
     }
   }
   dh = crypto_dh_new();
-  SSL_CTX_set_tmp_dh(result->ctx, dh->dh);
+  SSL_CTX_set_tmp_dh(result->ctx, _crypto_dh_env_get_dh(dh));
   crypto_dh_free(dh);
   SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER,
                      always_accept_verify_cb);
diff --git a/src/or/circuit.c b/src/or/circuit.c
index d573464a9..1d5103bbb 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -354,7 +354,7 @@ circuit_t *circuit_get_next_by_pk_and_purpose(circuit_t *start,
       continue;
     if (circ->purpose != purpose)
       continue;
-    if (!memcmp(circ->rend_pk_digest, digest, CRYPTO_SHA1_DIGEST_LEN))
+    if (!memcmp(circ->rend_pk_digest, digest, DIGEST_LEN))
       return circ;
   }
   return NULL;
@@ -1373,29 +1373,27 @@ int circuit_extend(cell_t *cell, circuit_t *circ) {
  */
 int circuit_init_cpath_crypto(crypt_path_t *cpath, char *key_data)
 {
-  unsigned char iv[16];
+  unsigned char iv[CIPHER_IV_LEN];
   assert(cpath && key_data);
   assert(!(cpath->f_crypto || cpath->b_crypto ||
            cpath->f_digest || cpath->b_digest));
 
-  memset(iv, 0, 16);
+  memset(iv, 0, CIPHER_IV_LEN);
 
   log_fn(LOG_DEBUG,"hop init digest forward 0x%.8x, backward 0x%.8x.",
          (unsigned int)*(uint32_t*)key_data, (unsigned int)*(uint32_t*)(key_data+20));
-  cpath->f_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
-  crypto_digest_add_bytes(cpath->f_digest, key_data, 20);
-  cpath->b_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
-  crypto_digest_add_bytes(cpath->b_digest, key_data+20, 20);
+  cpath->f_digest = crypto_new_digest_env();
+  crypto_digest_add_bytes(cpath->f_digest, key_data, DIGEST_LEN);
+  cpath->b_digest = crypto_new_digest_env();
+  crypto_digest_add_bytes(cpath->b_digest, key_data+DIGEST_LEN, DIGEST_LEN);
 
   log_fn(LOG_DEBUG,"hop init cipher forward 0x%.8x, backward 0x%.8x.",
-        (unsigned int)*(uint32_t*)(key_data+40), (unsigned int)*(uint32_t*)(key_data+40+16));
-  if (!(cpath->f_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,key_data+40,iv,1))) {
+         (unsigned int)*(uint32_t*)(key_data+40), (unsigned int)*(uint32_t*)(key_data+40+16));
+  if (!(cpath->f_crypto = crypto_create_init_cipher(key_data+40,iv,1))) {
     log(LOG_WARN,"forward cipher initialization failed.");
     return -1;
   }
-  if (!(cpath->b_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,key_data+40+16,iv,0))) {
+  if (!(cpath->b_crypto = crypto_create_init_cipher(key_data+40+16,iv,0))) {
     log(LOG_WARN,"backward cipher initialization failed.");
     return -1;
   }
@@ -1429,7 +1427,7 @@ int circuit_finish_handshake(circuit_t *circ, char *reply) {
   crypto_dh_free(hop->handshake_state); /* don't need it anymore */
   hop->handshake_state = NULL;
   /* Remember hash of g^xy */
-  memcpy(hop->handshake_digest, reply+DH_KEY_LEN, CRYPTO_SHA1_DIGEST_LEN);
+  memcpy(hop->handshake_digest, reply+DH_KEY_LEN, DIGEST_LEN);
 
   if (circuit_init_cpath_crypto(hop, keys)<0) {
     return -1;
diff --git a/src/or/onion.c b/src/or/onion.c
index 1fdd65ac9..f004f0367 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -122,10 +122,10 @@ void onion_pending_remove(circuit_t *circ) {
 
 /* given a response payload and keys, initialize, then send a created cell back */
 int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *keys) {
-  unsigned char iv[16];
+  unsigned char iv[CIPHER_IV_LEN];
   cell_t cell;
 
-  memset(iv, 0, 16);
+  memset(iv, 0, CIPHER_IV_LEN);
 
   memset(&cell, 0, sizeof(cell_t));
   cell.command = CELL_CREATED;
@@ -139,25 +139,23 @@ int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *key
 
   log_fn(LOG_INFO,"init digest forward 0x%.8x, backward 0x%.8x.",
          (unsigned int)*(uint32_t*)(keys), (unsigned int)*(uint32_t*)(keys+20));
-  circ->n_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
-  crypto_digest_add_bytes(circ->n_digest, keys, 20);
-  circ->p_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
-  crypto_digest_add_bytes(circ->p_digest, keys+20, 20);
+  circ->n_digest = crypto_new_digest_env();
+  crypto_digest_add_bytes(circ->n_digest, keys, DIGEST_LEN);
+  circ->p_digest = crypto_new_digest_env();
+  crypto_digest_add_bytes(circ->p_digest, keys+DIGEST_LEN, DIGEST_LEN);
 
   log_fn(LOG_DEBUG,"init cipher forward 0x%.8x, backward 0x%.8x.",
          (unsigned int)*(uint32_t*)(keys+40), (unsigned int)*(uint32_t*)(keys+40+16));
-  if (!(circ->n_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40,iv,0))) {
+  if (!(circ->n_crypto = crypto_create_init_cipher(keys+40,iv,0))) {
     log_fn(LOG_WARN,"Cipher initialization failed (n).");
     return -1;
   }
-  if (!(circ->p_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40+16,iv,1))) {
+  if (!(circ->p_crypto = crypto_create_init_cipher(keys+40+16,iv,1))) {
     log_fn(LOG_WARN,"Cipher initialization failed (p).");
     return -1;
   }
 
-  memcpy(circ->handshake_digest, cell.payload+DH_KEY_LEN, CRYPTO_SHA1_DIGEST_LEN);
+  memcpy(circ->handshake_digest, cell.payload+DH_KEY_LEN, DIGEST_LEN);
 
   connection_or_write_cell_to_buf(&cell, circ->p_conn);
   log_fn(LOG_DEBUG,"Finished sending 'created' cell.");
@@ -605,13 +603,13 @@ onion_skin_create(crypto_pk_env_t *dest_router_key,
 
   /* set meeting point, meeting cookie, etc here. Leave zero for now. */
 
-  cipher = crypto_create_init_cipher(ONION_CIPHER, challenge, iv, 1);
+  cipher = crypto_create_init_cipher(challenge, iv, 1);
 
   if (!cipher)
     goto err;
 
   if (crypto_pk_public_encrypt(dest_router_key, challenge, pkbytes,
-                               onion_skin_out, RSA_NO_PADDING)==-1)
+                               onion_skin_out, PK_NO_PADDING)==-1)
     goto err;
 
   if (crypto_cipher_encrypt(cipher, challenge+pkbytes, ONIONSKIN_CHALLENGE_LEN-pkbytes,
@@ -655,7 +653,7 @@ onion_skin_server_handshake(char *onion_skin, /* ONIONSKIN_CHALLENGE_LEN bytes *
 
   if (crypto_pk_private_decrypt(private_key,
                                 onion_skin, pkbytes,
-                                challenge, RSA_NO_PADDING) == -1)
+                                challenge, PK_NO_PADDING) == -1)
     goto err;
 
 #ifdef DEBUG_ONION_SKINS
@@ -664,7 +662,7 @@ onion_skin_server_handshake(char *onion_skin, /* ONIONSKIN_CHALLENGE_LEN bytes *
   puts("");
 #endif
 
-  cipher = crypto_create_init_cipher(ONION_CIPHER, challenge, iv, 0);
+  cipher = crypto_create_init_cipher(challenge, iv, 0);
 
   if (crypto_cipher_decrypt(cipher, onion_skin+pkbytes, ONIONSKIN_CHALLENGE_LEN-pkbytes,
                             challenge+pkbytes))
diff --git a/src/or/or.h b/src/or/or.h
index c43d9869a..d14496458 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -251,13 +251,6 @@
 /* Reasons used by connection_mark_for_close */
 #define CLOSE_REASON_UNUSED_OR_CONN 100
 
-/* default cipher function */
-#define DEFAULT_CIPHER CRYPTO_CIPHER_AES_CTR
-/* Used to en/decrypt onion skins */
-#define ONION_CIPHER      DEFAULT_CIPHER
-/* Used to en/decrypt RELAY cells */
-#define CIRCUIT_CIPHER    DEFAULT_CIPHER
-
 #define CELL_DIRECTION_IN 1
 #define CELL_DIRECTION_OUT 2
 #define EDGE_EXIT CONN_TYPE_EXIT
@@ -482,7 +475,7 @@ struct crypt_path_t {
   crypto_digest_env_t *b_digest;
 
   crypto_dh_env_t *handshake_state;
-  char handshake_digest[CRYPTO_SHA1_DIGEST_LEN];/* KH in tor-spec.txt */
+  char handshake_digest[DIGEST_LEN];/* KH in tor-spec.txt */
 
   uint32_t addr;
   uint16_t port;
@@ -501,7 +494,7 @@ struct crypt_path_t {
 #define DH_KEY_LEN CRYPTO_DH_SIZE
 #define ONIONSKIN_CHALLENGE_LEN (16+DH_KEY_LEN)
 #define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+20)
-#define REND_COOKIE_LEN CRYPTO_SHA1_DIGEST_LEN
+#define REND_COOKIE_LEN DIGEST_LEN
 
 typedef struct crypt_path_t crypt_path_t;
 
@@ -545,7 +538,7 @@ struct circuit_t {
   crypt_path_t *cpath;
 
   char onionskin[ONIONSKIN_CHALLENGE_LEN]; /* for storage while onionskin pending */
-  char handshake_digest[CRYPTO_SHA1_DIGEST_LEN]; /* Stores KH for intermediate hops */
+  char handshake_digest[DIGEST_LEN]; /* Stores KH for intermediate hops */
 
   time_t timestamp_created;
   time_t timestamp_dirty; /* when the circuit was first used, or 0 if clean */
@@ -563,7 +556,7 @@ struct circuit_t {
   /* rend_pk_digest holds a hash of location-hidden service's PK if
    * purpose is INTRO_POINT or S_ESTABLISH_INTRO or S_RENDEZVOUSING
    */
-  char rend_pk_digest[CRYPTO_SHA1_DIGEST_LEN];
+  char rend_pk_digest[DIGEST_LEN];
 
   /* Holds rendezvous cookie if purpose is REND_POINT_WAITING or
    * C_ESTABLISH_REND. Filled with zeroes otherwise.
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index c3ad05cc4..f57e17727 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -112,7 +112,7 @@ rend_service_descriptor_t *rend_parse_service_descriptor(
 
 int rend_get_service_id(crypto_pk_env_t *pk, char *out)
 {
-  char buf[CRYPTO_SHA1_DIGEST_LEN];
+  char buf[DIGEST_LEN];
   assert(pk);
   if (crypto_pk_get_digest(pk, buf) < 0)
     return -1;
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index 6c9a61090..0fd6c7590 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -42,7 +42,7 @@ rend_mid_establish_intro(circuit_t *circ, char *request, int request_len)
   /* Next 20 bytes: Hash of handshake_digest | "INTRODUCE" */
   memcpy(buf, circ->handshake_digest, 20);
   memcpy(buf+20, "INTRODUCE", 9);
-  if (crypto_SHA_digest(buf, 29, expected_digest)<0) {
+  if (crypto_digest(buf, 29, expected_digest)<0) {
     log_fn(LOG_WARN, "Error computing digest");
     goto err;
   }
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index ae6488dc1..57e4ce17f 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -352,7 +352,7 @@ rend_service_introduce(circuit_t *circuit, char *request, int request_len)
   }
   /* Next N bytes is encrypted with service key */
   len = crypto_pk_private_hybrid_decrypt(
-       service->private_key,request,request_len-20,buf, RSA_PKCS1_PADDING);
+       service->private_key,request,request_len-20,buf, PK_PKCS1_PADDING);
   if (len<0) {
     log_fn(LOG_WARN, "Couldn't decrypt INTRODUCE2 cell");
     return -1;
@@ -404,7 +404,7 @@ rend_service_introduce(circuit_t *circuit, char *request, int request_len)
   assert(launched->build_state);
   /* Fill in the circuit's state. */
   memcpy(launched->rend_pk_digest, circuit->rend_pk_digest,
-         CRYPTO_SHA1_DIGEST_LEN);
+         DIGEST_LEN);
   memcpy(launched->rend_cookie, r_cookie, REND_COOKIE_LEN);
   launched->build_state->pending_final_cpath = cpath =
     tor_malloc_zero(sizeof(crypt_path_t));
@@ -442,7 +442,7 @@ rend_service_launch_establish_intro(rend_service_t *service, char *nickname)
            nickname);
     return -1;
   }
-  memcpy(launched->rend_pk_digest, service->pk_digest, CRYPTO_SHA1_DIGEST_LEN);
+  memcpy(launched->rend_pk_digest, service->pk_digest, DIGEST_LEN);
 
   return 0;
 }
@@ -456,7 +456,7 @@ rend_service_intro_is_ready(circuit_t *circuit)
   rend_service_t *service;
   int len, r;
   char buf[RELAY_PAYLOAD_SIZE];
-  char auth[CRYPTO_SHA1_DIGEST_LEN + 10];
+  char auth[DIGEST_LEN + 10];
   char hexid[9];
 
   assert(circuit->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO);
@@ -479,9 +479,9 @@ rend_service_intro_is_ready(circuit_t *circuit)
                               RELAY_PAYLOAD_SIZE-2);
   set_uint16(buf, len);
   len += 2;
-  memcpy(auth, circuit->cpath->prev->handshake_digest, CRYPTO_SHA1_DIGEST_LEN);
-  memcpy(auth+CRYPTO_SHA1_DIGEST_LEN, "INTRODUCE", 9);
-  if (crypto_SHA_digest(auth, CRYPTO_SHA1_DIGEST_LEN+9, buf+len))
+  memcpy(auth, circuit->cpath->prev->handshake_digest, DIGEST_LEN);
+  memcpy(auth+DIGEST_LEN, "INTRODUCE", 9);
+  if (crypto_digest(auth, DIGEST_LEN+9, buf+len))
     goto err;
   len += 20;
   r = crypto_pk_private_sign_digest(service->private_key, buf, len, buf+len);
@@ -543,7 +543,7 @@ rend_service_rendezvous_is_ready(circuit_t *circuit)
     goto err;
   }
   memcpy(buf+REND_COOKIE_LEN+DH_KEY_LEN, hop->handshake_digest,
-         CRYPTO_SHA1_DIGEST_LEN);
+         DIGEST_LEN);
 
   /* Send the cell */
   if (connection_edge_send_command(NULL, circuit, RELAY_COMMAND_RENDEZVOUS1,
diff --git a/src/or/router.c b/src/or/router.c
index 59b257c97..4bface204 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -54,7 +54,7 @@ crypto_pk_env_t *init_key_from_file(const char *fname)
   int fd = -1;
   FILE *file = NULL;
 
-  if (!(prkey = crypto_new_pk_env(CRYPTO_PK_RSA))) {
+  if (!(prkey = crypto_new_pk_env())) {
     log(LOG_ERR, "Error creating crypto environment.");
     goto error;
   }
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 5c54c6db0..2f41fa1a1 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1356,7 +1356,7 @@ get_next_token(const char **s, where_syntax where) {
     if (strncmp(next, "-----END RSA PUBLIC KEY-----\n", 29))
       RET_ERR("Malformed object: mismatched end line");
     next = strchr(next,'\n')+1;
-    tok->key = crypto_new_pk_env(CRYPTO_PK_RSA);
+    tok->key = crypto_new_pk_env();
     if (crypto_pk_read_public_key_from_string(tok->key, obstart, next-obstart))
       RET_ERR("Couldn't parse public key.");
     *s = next;
@@ -1490,7 +1490,7 @@ static int router_get_hash_impl(const char *s, char *digest,
   }
   ++end;
 
-  if (crypto_SHA_digest(start, end-start, digest)) {
+  if (crypto_digest(start, end-start, digest)) {
     log_fn(LOG_WARN,"couldn't compute digest");
     return -1;
   }
diff --git a/src/or/test.c b/src/or/test.c
index 055fc332d..eb0453277 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -243,12 +243,6 @@ test_crypto()
   char *data1, *data2, *data3, *cp;
   FILE *f;
   int i, j, p, len;
-  int str_ciphers[] = { CRYPTO_CIPHER_IDENTITY,
-                        CRYPTO_CIPHER_DES,
-                        CRYPTO_CIPHER_RC4,
-                        CRYPTO_CIPHER_3DES,
-                        CRYPTO_CIPHER_AES_CTR,
-                        -1 };
 
   data1 = tor_malloc(1024);
   data2 = tor_malloc(1024);
@@ -261,6 +255,7 @@ test_crypto()
   crypto_rand(100, data2);
   test_memneq(data1,data2,100);
 
+#if 0
   /* Try out identity ciphers. */
   env1 = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY);
   test_neq(env1, 0);
@@ -273,90 +268,82 @@ test_crypto()
   crypto_cipher_encrypt(env1, data1, 1024, data2);
   test_memeq(data1, data2, 1024);
   crypto_free_cipher_env(env1);
+#endif
 
-  /* Now, test encryption and decryption with stream ciphers. */
+  /* Now, test encryption and decryption with stream cipher. */
   data1[0]='\0';
   for(i = 1023; i>0; i -= 35)
     strncat(data1, "Now is the time for all good onions", i);
-  for(i=0; str_ciphers[i] >= 0; ++i) {
-    /* For each cipher... */
-    memset(data2, 0, 1024);
-    memset(data3, 0, 1024);
-    env1 = crypto_new_cipher_env(str_ciphers[i]);
-    test_neq(env1, 0);
-    env2 = crypto_new_cipher_env(str_ciphers[i]);
-    test_neq(env2, 0);
-    j = crypto_cipher_generate_key(env1);
-    if (str_ciphers[i] != CRYPTO_CIPHER_IDENTITY) {
-      crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
-    }
-    crypto_cipher_set_iv(env1, "12345678901234567890");
-    crypto_cipher_set_iv(env2, "12345678901234567890");
-    crypto_cipher_encrypt_init_cipher(env1);
-    crypto_cipher_decrypt_init_cipher(env2);
-
-    /* Try encrypting 512 chars. */
-    crypto_cipher_encrypt(env1, data1, 512, data2);
-    crypto_cipher_decrypt(env2, data2, 512, data3);
-    test_memeq(data1, data3, 512);
-    if (str_ciphers[i] == CRYPTO_CIPHER_IDENTITY) {
-      test_memeq(data1, data2, 512);
-    } else {
-      test_memneq(data1, data2, 512);
-    }
-    /* Now encrypt 1 at a time, and get 1 at a time. */
-    for (j = 512; j < 560; ++j) {
-      crypto_cipher_encrypt(env1, data1+j, 1, data2+j);
-    }
-    for (j = 512; j < 560; ++j) {
-      crypto_cipher_decrypt(env2, data2+j, 1, data3+j);
-    }
-    test_memeq(data1, data3, 560);
-    /* Now encrypt 3 at a time, and get 5 at a time. */
-    for (j = 560; j < 1024-5; j += 3) {
-      crypto_cipher_encrypt(env1, data1+j, 3, data2+j);
-    }
-    for (j = 560; j < 1024-5; j += 5) {
-      crypto_cipher_decrypt(env2, data2+j, 5, data3+j);
-    }
-    test_memeq(data1, data3, 1024-5);
-    /* Now make sure that when we encrypt with different chunk sizes, we get
-       the same results. */
-    crypto_free_cipher_env(env2);
-
-    memset(data3, 0, 1024);
-    env2 = crypto_new_cipher_env(str_ciphers[i]);
-    test_neq(env2, 0);
-    if (str_ciphers[i] != CRYPTO_CIPHER_IDENTITY) {
-      crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
-    }
-    crypto_cipher_set_iv(env2, "12345678901234567890");
-    crypto_cipher_encrypt_init_cipher(env2);
-    for (j = 0; j < 1024-16; j += 17) {
-      crypto_cipher_encrypt(env2, data1+j, 17, data3+j);
-    }
-    for (j= 0; j < 1024-16; ++j) {
-      if (data2[j] != data3[j]) {
-        printf("%d:  %d\t%d\n", j, (int) data2[j], (int) data3[j]);
-      }
+
+  memset(data2, 0, 1024);
+  memset(data3, 0, 1024);
+  env1 = crypto_new_cipher_env();
+  test_neq(env1, 0);
+  env2 = crypto_new_cipher_env();
+  test_neq(env2, 0);
+  j = crypto_cipher_generate_key(env1);
+  crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
+  crypto_cipher_set_iv(env1, "12345678901234567890");
+  crypto_cipher_set_iv(env2, "12345678901234567890");
+  crypto_cipher_encrypt_init_cipher(env1);
+  crypto_cipher_decrypt_init_cipher(env2);
+
+  /* Try encrypting 512 chars. */
+  crypto_cipher_encrypt(env1, data1, 512, data2);
+  crypto_cipher_decrypt(env2, data2, 512, data3);
+  test_memeq(data1, data3, 512);
+  test_memneq(data1, data2, 512);
+
+  /* Now encrypt 1 at a time, and get 1 at a time. */
+  for (j = 512; j < 560; ++j) {
+    crypto_cipher_encrypt(env1, data1+j, 1, data2+j);
+  }
+  for (j = 512; j < 560; ++j) {
+    crypto_cipher_decrypt(env2, data2+j, 1, data3+j);
+  }
+  test_memeq(data1, data3, 560);
+  /* Now encrypt 3 at a time, and get 5 at a time. */
+  for (j = 560; j < 1024-5; j += 3) {
+    crypto_cipher_encrypt(env1, data1+j, 3, data2+j);
+  }
+  for (j = 560; j < 1024-5; j += 5) {
+    crypto_cipher_decrypt(env2, data2+j, 5, data3+j);
+  }
+  test_memeq(data1, data3, 1024-5);
+  /* Now make sure that when we encrypt with different chunk sizes, we get
+     the same results. */
+  crypto_free_cipher_env(env2);
+
+  memset(data3, 0, 1024);
+  env2 = crypto_new_cipher_env();
+  test_neq(env2, 0);
+  crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
+  crypto_cipher_set_iv(env2, "12345678901234567890");
+  crypto_cipher_encrypt_init_cipher(env2);
+  for (j = 0; j < 1024-16; j += 17) {
+    crypto_cipher_encrypt(env2, data1+j, 17, data3+j);
+  }
+  for (j= 0; j < 1024-16; ++j) {
+    if (data2[j] != data3[j]) {
+      printf("%d:  %d\t%d\n", j, (int) data2[j], (int) data3[j]);
     }
-    test_memeq(data2, data3, 1024-16);
-    crypto_free_cipher_env(env1);
-    crypto_free_cipher_env(env2);
   }
+  test_memeq(data2, data3, 1024-16);
+  crypto_free_cipher_env(env1);
+  crypto_free_cipher_env(env2);
 
   /* Test vectors for stream ciphers. */
   /* XXXX Look up some test vectors for the ciphers and make sure we match. */
 
   /* Test SHA-1 with a test vector from the specification. */
-  i = crypto_SHA_digest("abc", 3, data1);
+  i = crypto_digest("abc", 3, data1);
   test_memeq(data1,
              "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78"
              "\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
 
   /* Public-key ciphers */
-  pk1 = crypto_new_pk_env(CRYPTO_PK_RSA);
-  pk2 = crypto_new_pk_env(CRYPTO_PK_RSA);
+  pk1 = crypto_new_pk_env();
+  pk2 = crypto_new_pk_env();
   test_assert(pk1 && pk2);
   test_assert(! crypto_pk_generate_key(pk1));
   test_assert(! crypto_pk_write_public_key_to_string(pk1, &cp, &i));
@@ -367,25 +354,25 @@ test_crypto()
   test_eq(128, crypto_pk_keysize(pk2));
 
   test_eq(128, crypto_pk_public_encrypt(pk2, "Hello whirled.", 15, data1,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
   test_eq(128, crypto_pk_public_encrypt(pk1, "Hello whirled.", 15, data2,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
   /* oaep padding should make encryption not match */
   test_memneq(data1, data2, 128);
   test_eq(15, crypto_pk_private_decrypt(pk1, data1, 128, data3,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
   test_streq(data3, "Hello whirled.");
   memset(data3, 0, 1024);
   test_eq(15, crypto_pk_private_decrypt(pk1, data2, 128, data3,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
   test_streq(data3, "Hello whirled.");
   /* Can't decrypt with public key. */
   test_eq(-1, crypto_pk_private_decrypt(pk2, data2, 128, data3,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
   /* Try again with bad padding */
   memcpy(data2+1, "XYZZY", 5);  /* This has fails ~ once-in-2^40 */
   test_eq(-1, crypto_pk_private_decrypt(pk1, data2, 128, data3,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
 
   /* File operations: save and load private key */
   f = fopen("/tmp/tor_test/pkey1", "wb");
@@ -395,11 +382,11 @@ test_crypto()
   test_assert(! crypto_pk_read_private_key_from_file(pk2, f));
   fclose(f);
   test_eq(15, crypto_pk_private_decrypt(pk2, data1, 128, data3,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
   test_assert(! crypto_pk_read_private_key_from_filename(pk2,
                                                "/tmp/tor_test/pkey1"));
   test_eq(15, crypto_pk_private_decrypt(pk2, data1, 128, data3,
-                                        RSA_PKCS1_OAEP_PADDING));
+                                        PK_PKCS1_OAEP_PADDING));
 
   /* Now try signing. */
   strcpy(data1, "Ossifrage");
@@ -429,8 +416,8 @@ test_crypto()
       memset(data3,0,1024);
       if (i == 0 && j < 129)
         continue;
-      p = (i==0)?RSA_NO_PADDING:
-        (i==1)?RSA_PKCS1_PADDING:RSA_PKCS1_OAEP_PADDING;
+      p = (i==0)?PK_NO_PADDING:
+        (i==1)?PK_PKCS1_PADDING:PK_PKCS1_OAEP_PADDING;
       len = crypto_pk_public_hybrid_encrypt(pk1,data1,j,data2,p);
       test_assert(len>=0);
       len = crypto_pk_private_hybrid_decrypt(pk1,data2,len,data3,p);
@@ -626,7 +613,7 @@ test_onion_handshake() {
   /* shared */
   crypto_pk_env_t *pk = NULL;
 
-  pk = crypto_new_pk_env(CRYPTO_PK_RSA);
+  pk = crypto_new_pk_env();
   test_assert(! crypto_pk_generate_key(pk));
 
   /* client handshake 1. */
@@ -669,9 +656,9 @@ test_dir_format()
   struct exit_policy_t ex1, ex2;
   routerlist_t *dir1 = NULL, *dir2 = NULL;
 
-  test_assert( (pk1 = crypto_new_pk_env(CRYPTO_PK_RSA)) );
-  test_assert( (pk2 = crypto_new_pk_env(CRYPTO_PK_RSA)) );
-  test_assert( (pk3 = crypto_new_pk_env(CRYPTO_PK_RSA)) );
+  test_assert( (pk1 = crypto_new_pk_env()) );
+  test_assert( (pk2 = crypto_new_pk_env()) );
+  test_assert( (pk3 = crypto_new_pk_env()) );
   test_assert(! crypto_pk_generate_key(pk1));
   test_assert(! crypto_pk_generate_key(pk2));
   test_assert(! crypto_pk_generate_key(pk3));
@@ -835,7 +822,7 @@ void test_rend_fns()
   int len;
   crypto_pk_env_t *pk1;
   time_t now;
-  pk1 = crypto_new_pk_env(CRYPTO_PK_RSA);
+  pk1 = crypto_new_pk_env();
 
   test_assert(!crypto_pk_generate_key(pk1));
   d1 = tor_malloc_zero(sizeof(rend_service_descriptor_t));
-- 
cgit v1.2.3