static OSSL_FUNC_cipher_gettable_ctx_params_fn chacha20_poly1305_gettable_ctx_params;
static OSSL_FUNC_cipher_settable_ctx_params_fn chacha20_poly1305_settable_ctx_params;
#define chacha20_poly1305_gettable_params ossl_cipher_generic_gettable_params
-#define chacha20_poly1305_update chacha20_poly1305_cipher
static void *chacha20_poly1305_newctx(void *provctx)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
return 0;
}
+ ctx->iv_state = IV_STATE_UNINITIALISED;
}
if (p.tag != NULL) {
ret = ossl_cipher_generic_einit(vctx, key, keylen, iv, ivlen, NULL);
if (ret && iv != NULL) {
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+ PROV_CHACHA20_POLY1305_CTX *cctx = (PROV_CHACHA20_POLY1305_CTX *)vctx;
PROV_CIPHER_HW_CHACHA20_POLY1305 *hw = (PROV_CIPHER_HW_CHACHA20_POLY1305 *)ctx->hw;
hw->initiv(ctx);
+ cctx->iv_state = IV_STATE_BUFFERED;
}
if (ret && !chacha20_poly1305_set_ctx_params(vctx, params))
ret = 0;
ret = ossl_cipher_generic_dinit(vctx, key, keylen, iv, ivlen, NULL);
if (ret && iv != NULL) {
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+ PROV_CHACHA20_POLY1305_CTX *cctx = (PROV_CHACHA20_POLY1305_CTX *)vctx;
PROV_CIPHER_HW_CHACHA20_POLY1305 *hw = (PROV_CIPHER_HW_CHACHA20_POLY1305 *)ctx->hw;
hw->initiv(ctx);
+ cctx->iv_state = IV_STATE_BUFFERED;
}
if (ret && !chacha20_poly1305_set_ctx_params(vctx, params))
ret = 0;
return 1;
}
+static int chacha20_poly1305_update(void *vctx, unsigned char *out,
+ size_t *outl, size_t outsize,
+ const unsigned char *in, size_t inl)
+{
+ PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx;
+
+ if (ctx->iv_state == IV_STATE_FINISHED)
+ return 0;
+
+ return chacha20_poly1305_cipher(vctx, out, outl, outsize, in, inl);
+}
+
static int chacha20_poly1305_final(void *vctx, unsigned char *out, size_t *outl,
size_t outsize)
{
return 0;
*outl = 0;
+
+ /* Don't reuse the IV */
+ ctx->iv_state = IV_STATE_FINISHED;
return 1;
}