-/**
- * encrypt a buffer using an RSA key
- *
- * \param rsa: public rsa key
- * \param inbuf the input buffer
- * \param len the length of \a inbuf
- * \param outbuf the output buffer
- *
- * \return The size of the encrypted data on success, negative on errors
- *
- * \sa RSA_public_encrypt(3)
- */
-int para_encrypt_buffer(RSA *rsa, unsigned char *inbuf,
- const unsigned len, unsigned char *outbuf)
+void free_asymmetric_key(struct asymmetric_key *key)
+{
+ if (!key)
+ return;
+ RSA_free(key->rsa);
+ free(key);
+}
+
+int priv_decrypt(const char *key_file, unsigned char *outbuf,
+ unsigned char *inbuf, int inlen)
+{
+ struct asymmetric_key *priv;
+ int ret;
+
+ if (inlen < 0)
+ return -E_RSA;
+ ret = get_asymmetric_key(key_file, LOAD_PRIVATE_KEY, &priv);
+ if (ret < 0)
+ return ret;
+ /*
+ * RSA is vulnerable to timing attacks. Generate a random blinding
+ * factor to protect against this kind of attack.
+ */
+ ret = -E_BLINDING;
+ if (RSA_blinding_on(priv->rsa, NULL) == 0)
+ goto out;
+ ret = RSA_private_decrypt(inlen, inbuf, outbuf, priv->rsa,
+ RSA_PKCS1_OAEP_PADDING);
+ RSA_blinding_off(priv->rsa);
+ if (ret <= 0)
+ ret = -E_DECRYPT;
+out:
+ free_asymmetric_key(priv);
+ return ret;
+}
+
+int pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf,
+ unsigned len, unsigned char *outbuf)
+{
+ int ret, flen = len; /* RSA_public_encrypt expects a signed int */
+
+ if (flen < 0)
+ return -E_ENCRYPT;
+ ret = RSA_public_encrypt(flen, inbuf, outbuf, pub->rsa,
+ RSA_PKCS1_OAEP_PADDING);
+ return ret < 0? -E_ENCRYPT : ret;
+}
+
+struct stream_cipher {
+ RC4_KEY key;
+};
+
+struct stream_cipher *sc_new(const unsigned char *data, int len)
+{
+ struct stream_cipher *sc = para_malloc(sizeof(*sc));
+ RC4_set_key(&sc->key, len, data);
+ return sc;
+}
+
+void sc_free(struct stream_cipher *sc)