- ret = EVP_EncryptInit_ex(&ctx, skey->cipher, NULL, skey->ekey, NULL);
- if (ret == 0) goto done;
- totlen = 0;
-
- outlen = cipher->length;
- ret = EVP_EncryptUpdate(&ctx, cipher->value, &outlen, rbuf, sizeof(rbuf));
- if (ret == 0) goto done;
- totlen += outlen;
-
- outlen = cipher->length - totlen;
- ret = EVP_EncryptUpdate(&ctx, &cipher->value[totlen], &outlen,
- plain->value, plain->length);
- if (ret == 0) goto done;
- totlen += outlen;
-
- outlen = cipher->length - totlen;
- ret = EVP_EncryptFinal_ex(&ctx, &cipher->value[totlen], &outlen);
- if (ret == 0) goto done;
- totlen += outlen;
-
- /* now MAC the buffer */
- HMAC_CTX_init(&hmac_ctx);
-
- ret = HMAC_Init_ex(&hmac_ctx, skey->hkey,
- skey->cipher->key_len, skey->md, NULL);
- if (ret == 0) goto done;
-
- ret = HMAC_Update(&hmac_ctx, cipher->value, totlen);
- if (ret == 0) goto done;
-
- ret = HMAC_Final(&hmac_ctx, &cipher->value[totlen], &len);
- if (ret == 0) goto done;
+ /* Generate IV. */
+ ret = apr_generate_random_bytes(cipher->value, skey->cipher->iv_len);
+ if (ret != 0) goto done;
+ cipher->length = skey->cipher->iv_len;
+
+ ret = EVP_EncryptInit_ex(&ctx, skey->cipher, NULL,
+ skey->ekey, cipher->value);
+ if (ret != 1) goto done;
+
+ /* Encrypt the data. */
+ outlen = 0;
+ ret = EVP_EncryptUpdate(&ctx, &cipher->value[cipher->length],
+ &outlen, plain->value, plain->length);
+ if (ret != 1) goto done;
+ cipher->length += outlen;
+
+ outlen = 0;
+ ret = EVP_EncryptFinal_ex(&ctx, &cipher->value[cipher->length], &outlen);
+ if (ret != 1) goto done;
+ cipher->length += outlen;
+
+ /* Get the tag */
+ ret = EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, TAGSIZE,
+ &cipher->value[cipher->length]);
+ if (ret != 1) goto done;
+ cipher->length += TAGSIZE;