- unsigned char *inbuf = (unsigned char*) make_message("%lu", challenge_nr);
- int ret = para_encrypt_buffer(rsa, inbuf, strlen((char *)inbuf), outbuf);
- free(inbuf);
- return ret;
+ struct stream_cipher *sc = para_malloc(sizeof(*sc));
+
+ assert(len >= 2 * AES_CRT128_BLOCK_SIZE);
+ sc->aes = EVP_CIPHER_CTX_new();
+ EVP_EncryptInit_ex(sc->aes, EVP_aes_128_ctr(), NULL, data,
+ data + AES_CRT128_BLOCK_SIZE);
+ return sc;
+}
+
+void sc_free(struct stream_cipher *sc)
+{
+ if (!sc)
+ return;
+ EVP_CIPHER_CTX_free(sc->aes);
+ free(sc);
+}
+
+static void aes_ctr128_crypt(EVP_CIPHER_CTX *ctx, struct iovec *src,
+ struct iovec *dst)
+{
+ int ret, inlen = src->iov_len, outlen, tmplen;
+
+ *dst = (typeof(*dst)) {
+ /* Add one for the terminating zero byte. */
+ .iov_base = para_malloc(inlen + 1),
+ .iov_len = inlen
+ };
+ ret = EVP_EncryptUpdate(ctx, dst->iov_base, &outlen, src->iov_base, inlen);
+ assert(ret != 0);
+ ret = EVP_EncryptFinal_ex(ctx, dst->iov_base + outlen, &tmplen);
+ assert(ret != 0);
+ outlen += tmplen;
+ ((char *)dst->iov_base)[outlen] = '\0';
+ dst->iov_len = outlen;