/* Test copying of contexts */ static void test_ctx_replace(EVP_CIPHER_CTX **pctx) { /* Make copy of context and replace original */ EVP_CIPHER_CTX *ctx_copy; ctx_copy = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_copy(ctx_copy, *pctx); EVP_CIPHER_CTX_free(*pctx); *pctx = ctx_copy; }
int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) { int bl; if (in->nlast_block == -1) return 0; if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx)) return 0; bl = EVP_CIPHER_CTX_block_size(&in->cctx); memcpy(out->k1, in->k1, bl); memcpy(out->k2, in->k2, bl); memcpy(out->tbl, in->tbl, bl); memcpy(out->last_block, in->last_block, bl); out->nlast_block = in->nlast_block; return 1; }
static VALUE ossl_cipher_copy(VALUE self, VALUE other) { EVP_CIPHER_CTX *ctx1, *ctx2; rb_check_frozen(self); if (self == other) return self; GetCipher(self, ctx1); SafeGetCipher(other, ctx2); if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) ossl_raise(eCipherError, NULL); return self; }
static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO *dbio; BIO_ENC_CTX *ctx,*dctx; long ret=1; int i; EVP_CIPHER_CTX **c_ctx; ctx=(BIO_ENC_CTX *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: ctx->ok=1; ctx->finished=0; EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL, ctx->cipher.encrypt); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_EOF: /* More to read */ if (ctx->cont <= 0) ret=1; else ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_WPENDING: ret=ctx->buf_len-ctx->buf_off; if (ret <= 0) ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_PENDING: /* More to read in buffer */ ret=ctx->buf_len-ctx->buf_off; if (ret <= 0) ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_FLUSH: /* do a final write */ again: while (ctx->buf_len != ctx->buf_off) { i=enc_write(b,NULL,0); if (i < 0) return i; } if (!ctx->finished) { ctx->finished=1; ctx->buf_off=0; ret=EVP_CipherFinal_ex(&(ctx->cipher), (unsigned char *)ctx->buf, &(ctx->buf_len)); ctx->ok=(int)ret; if (ret <= 0) break; /* push out the bytes */ goto again; } /* Finally flush the underlying BIO */ ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_C_GET_CIPHER_STATUS: ret=(long)ctx->ok; break; case BIO_C_DO_STATE_MACHINE: BIO_clear_retry_flags(b); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); BIO_copy_next_retry(b); break; case BIO_C_GET_CIPHER_CTX: c_ctx=(EVP_CIPHER_CTX **)ptr; (*c_ctx)= &(ctx->cipher); b->init=1; break; case BIO_CTRL_DUP: dbio=(BIO *)ptr; dctx=(BIO_ENC_CTX *)dbio->ptr; EVP_CIPHER_CTX_init(&dctx->cipher); ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher); if (ret) dbio->init=1; break; default: ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; } return(ret); }
static int test_contexts(const EVP_CIPHER *type, const int enc, const char *msg, int acpkm) { EVP_CIPHER_CTX *ctx, *save; unsigned char pt[TEST_SIZE] = {1}; unsigned char b[TEST_SIZE]; unsigned char c[TEST_SIZE]; unsigned char K[32] = {1}; unsigned char iv[16] = {1}; int outlen, tmplen; int ret = 0, test = 0; printf(cBLUE "%s test for %s\n" cNORM, enc ? "Encryption" : "Decryption", msg); /* produce base encryption */ ctx = EVP_CIPHER_CTX_new(); T(ctx); T(EVP_CipherInit_ex(ctx, type, NULL, K, iv, enc)); if (acpkm) T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); T(EVP_CIPHER_CTX_set_padding(ctx, 0)); T(EVP_CipherUpdate(ctx, b, &outlen, pt, sizeof(b))); T(EVP_CipherFinal_ex(ctx, b + outlen, &tmplen)); /* and now tests */ printf(" cloned contexts\n"); EVP_CIPHER_CTX_reset(ctx); EVP_CIPHER_CTX_reset(ctx); /* double call is intentional */ T(EVP_CipherInit_ex(ctx, type, NULL, K, iv, enc)); T(EVP_CIPHER_CTX_set_padding(ctx, 0)); if (acpkm) T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); save = ctx; int i; memset(c, 0, sizeof(c)); for (i = 0; i < TEST_SIZE / STEP_SIZE; i++) { EVP_CIPHER_CTX *copy = EVP_CIPHER_CTX_new(); T(copy); T(EVP_CIPHER_CTX_copy(copy, ctx)); if (save != ctx) /* else original context */ EVP_CIPHER_CTX_free(ctx); ctx = copy; T(EVP_CipherUpdate(ctx, c + STEP_SIZE * i, &outlen, pt + STEP_SIZE * i, STEP_SIZE)); } outlen = i * GRASSHOPPER_BLOCK_SIZE; T(EVP_CipherFinal_ex(ctx, c + outlen, &tmplen)); TEST_ASSERT(outlen != TEST_SIZE || memcmp(c, b, TEST_SIZE)); EVP_CIPHER_CTX_free(ctx); if (test) { printf(" b[%d] = ", outlen); hexdump(b, outlen); printf(" c[%d] = ", outlen); hexdump(c, outlen); } ret |= test; /* resume original context */ printf(" base context\n"); memset(c, 0, sizeof(c)); T(EVP_CipherUpdate(save, c, &outlen, pt, sizeof(c))); T(EVP_CipherFinal_ex(save, c + outlen, &tmplen)); TEST_ASSERT(outlen != TEST_SIZE || memcmp(c, b, TEST_SIZE)); EVP_CIPHER_CTX_cleanup(save); /* multiple calls are intentional */ EVP_CIPHER_CTX_cleanup(save); EVP_CIPHER_CTX_free(save); if (test) { printf(" b[%d] = ", outlen); hexdump(b, outlen); printf(" c[%d] = ", outlen); hexdump(c, outlen); } ret |= test; return ret; }