Convert TLSv1.3 code to use the new read side record layer

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18132)
This commit is contained in:
Matt Caswell 2022-04-29 17:13:23 +01:00
parent 10560aed15
commit 2b891e30ce
2 changed files with 274 additions and 65 deletions

View File

@ -104,6 +104,11 @@ struct ossl_record_layer_st
/* Only used by SSLv3 */
unsigned char mac_secret[EVP_MAX_MD_SIZE];
/* TLSv1.3 static IV */
unsigned char iv[EVP_MAX_IV_LENGTH];
size_t taglen;
/* Function pointers for version specific functions */
/* Function pointers for version specific functions */
struct record_functions_st *funcs;
@ -169,23 +174,6 @@ static int tls_provider_set_tls_parameters(OSSL_RECORD_LAYER *rl,
return 1;
}
static int tls_fail_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *ciph,
size_t taglen,
/* TODO(RECLAYER): This probably should not be an int */
int mactype,
const EVP_MD *md,
const SSL_COMP *comp,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *s)
{
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
@ -410,6 +398,51 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
return 1;
}
static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *ciph,
size_t taglen,
/* TODO(RECLAYER): This probably should not be an int */
int mactype,
const EVP_MD *md,
const SSL_COMP *comp,
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *s)
{
EVP_CIPHER_CTX *ciph_ctx;
int mode;
if (ivlen > sizeof(rl->iv)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
memcpy(rl->iv, iv, ivlen);
ciph_ctx = rl->enc_read_ctx = EVP_CIPHER_CTX_new();
if (ciph_ctx == NULL) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
return 0;
}
RECORD_LAYER_reset_read_sequence(&s->rlayer);
rl->taglen = taglen;
mode = EVP_CIPHER_get_mode(ciph);
if (EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, NULL, NULL) <= 0
|| !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL)
|| (mode == EVP_CIPH_CCM_MODE
&& !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL))
|| EVP_DecryptInit_ex(ciph_ctx, NULL, NULL, key, NULL) <= 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
}
return 1;
}
static int tls_any_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
int sending, SSL_MAC_BUF *macs, size_t macsize,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
@ -875,6 +908,139 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
return 1;
}
static int tls13_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
int sending, SSL_MAC_BUF *mac, size_t macsize,
/* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
{
EVP_CIPHER_CTX *ctx;
unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH];
size_t ivlen, offset, loop, hdrlen;
unsigned char *staticiv;
unsigned char *seq;
int lenu, lenf;
SSL3_RECORD *rec = &recs[0];
WPACKET wpkt;
const EVP_CIPHER *cipher;
int mode;
if (n_recs != 1) {
/* Should not happen */
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
if (sending) {
ctx = s->enc_write_ctx;
staticiv = s->write_iv;
seq = RECORD_LAYER_get_write_sequence(&s->rlayer);
} else {
ctx = rl->enc_read_ctx;
staticiv = rl->iv;
seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
}
cipher = EVP_CIPHER_CTX_get0_cipher(ctx);
if (cipher == NULL) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
mode = EVP_CIPHER_get_mode(cipher);
/*
* If we're sending an alert and ctx != NULL then we must be forcing
* plaintext alerts. If we're reading and ctx != NULL then we allow
* plaintext alerts at certain points in the handshake. If we've got this
* far then we have already validated that a plaintext alert is ok here.
*/
if (ctx == NULL || rec->type == SSL3_RT_ALERT) {
memmove(rec->data, rec->input, rec->length);
rec->input = rec->data;
return 1;
}
ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
if (!sending) {
/*
* Take off tag. There must be at least one byte of content type as
* well as the tag
*/
if (rec->length < rl->taglen + 1)
return 0;
rec->length -= rl->taglen;
}
/* Set up IV */
if (ivlen < SEQ_NUM_SIZE) {
/* Should not happen */
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
offset = ivlen - SEQ_NUM_SIZE;
memcpy(iv, staticiv, offset);
for (loop = 0; loop < SEQ_NUM_SIZE; loop++)
iv[offset + loop] = staticiv[offset + loop] ^ seq[loop];
/* Increment the sequence counter */
for (loop = SEQ_NUM_SIZE; loop > 0; loop--) {
++seq[loop - 1];
if (seq[loop - 1] != 0)
break;
}
if (loop == 0) {
/* Sequence has wrapped */
return 0;
}
if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0
|| (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
rl->taglen,
rec->data + rec->length) <= 0)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
/* Set up the AAD */
if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
|| !WPACKET_put_bytes_u8(&wpkt, rec->type)
|| !WPACKET_put_bytes_u16(&wpkt, rec->rec_version)
|| !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen)
|| !WPACKET_get_total_written(&wpkt, &hdrlen)
|| hdrlen != SSL3_RT_HEADER_LENGTH
|| !WPACKET_finish(&wpkt)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
WPACKET_cleanup(&wpkt);
return 0;
}
/*
* For CCM we must explicitly set the total plaintext length before we add
* any AAD.
*/
if ((mode == EVP_CIPH_CCM_MODE
&& EVP_CipherUpdate(ctx, NULL, &lenu, NULL,
(unsigned int)rec->length) <= 0)
|| EVP_CipherUpdate(ctx, NULL, &lenu, recheader,
sizeof(recheader)) <= 0
|| EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
(unsigned int)rec->length) <= 0
|| EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0
|| (size_t)(lenu + lenf) != rec->length) {
return 0;
}
if (sending) {
/* Add the tag */
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen,
rec->data + rec->length) <= 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
rec->length += rl->taglen;
}
return 1;
}
static const unsigned char ssl3_pad_1[48] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
@ -1102,7 +1268,6 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
return ret;
}
struct record_functions_st tls_any_funcs = {
tls_any_set_crypto_state,
tls_any_cipher,
@ -1110,8 +1275,8 @@ struct record_functions_st tls_any_funcs = {
};
struct record_functions_st tls_1_3_funcs = {
tls_fail_set_crypto_state,
NULL,
tls13_set_crypto_state,
tls13_cipher,
NULL
};
@ -1648,7 +1813,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
}
if (SSL_CONNECTION_IS_TLS13(s)
&& s->enc_read_ctx != NULL
&& rl->enc_read_ctx != NULL
&& !using_ktls) {
if (thisrr->type != SSL3_RT_APPLICATION_DATA
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
@ -1866,10 +2031,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
* TODO(RECLAYER): Only call rl functions once TLSv1.3/SSLv3 is moved to new
* record layer code
*/
if (!SSL_CONNECTION_IS_TLS13(s))
enc_err = rl->funcs->cipher(rl, rr, num_recs, 0, macbufs, mac_size, s);
else
enc_err = ssl->method->ssl3_enc->enc(s, rr, num_recs, 0, macbufs, mac_size);
enc_err = rl->funcs->cipher(rl, rr, num_recs, 0, macbufs, mac_size, s);
/*-
* enc_err is:
@ -1970,7 +2132,7 @@ static int tls_get_more_records(OSSL_RECORD_LAYER *rl,
}
if (SSL_CONNECTION_IS_TLS13(s)
&& s->enc_read_ctx != NULL
&& rl->enc_read_ctx != NULL
&& thisrr->type != SSL3_RT_ALERT) {
/*
* The following logic are irrelevant in KTLS: the kernel provides
@ -2288,6 +2450,7 @@ static OSSL_RECORD_LAYER *dtls_new_record_layer(OSSL_LIB_CTX *libctx,
static void tls_free(OSSL_RECORD_LAYER *rl)
{
/* TODO(RECLAYER): Cleanse sensitive fields */
BIO_free(rl->bio);
OPENSSL_free(rl);
}

View File

@ -344,12 +344,14 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
const unsigned char *hash,
const unsigned char *label,
size_t labellen, unsigned char *secret,
unsigned char *key, unsigned char *iv,
unsigned char *key, size_t *keylen,
unsigned char *iv, size_t *ivlen,
size_t *taglen,
EVP_CIPHER_CTX *ciph_ctx)
{
size_t ivlen, keylen, taglen;
int hashleni = EVP_MD_get_size(md);
size_t hashlen;
int mode;
/* Ensure cast to size_t is safe */
if (!ossl_assert(hashleni >= 0)) {
@ -364,11 +366,13 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
return 0;
}
keylen = EVP_CIPHER_get_key_length(ciph);
if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) {
*keylen = EVP_CIPHER_get_key_length(ciph);
mode = EVP_CIPHER_get_mode(ciph);
if (mode == EVP_CIPH_CCM_MODE) {
uint32_t algenc;
ivlen = EVP_CCM_TLS_IV_LEN;
*ivlen = EVP_CCM_TLS_IV_LEN;
if (s->s3.tmp.new_cipher != NULL) {
algenc = s->s3.tmp.new_cipher->algorithm_enc;
} else if (s->session->cipher != NULL) {
@ -382,27 +386,34 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
return 0;
}
if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8))
taglen = EVP_CCM8_TLS_TAG_LEN;
*taglen = EVP_CCM8_TLS_TAG_LEN;
else
taglen = EVP_CCM_TLS_TAG_LEN;
*taglen = EVP_CCM_TLS_TAG_LEN;
} else {
ivlen = EVP_CIPHER_get_iv_length(ciph);
taglen = 0;
if (mode == EVP_CIPH_GCM_MODE) {
*taglen = EVP_GCM_TLS_TAG_LEN;
} else {
/* CHACHA20P-POLY1305 */
*taglen = EVP_CHACHAPOLY_TLS_TAG_LEN;
}
*ivlen = EVP_CIPHER_get_iv_length(ciph);
}
if (!tls13_derive_key(s, md, secret, key, keylen)
|| !tls13_derive_iv(s, md, secret, iv, ivlen)) {
if (!tls13_derive_key(s, md, secret, key, *keylen)
|| !tls13_derive_iv(s, md, secret, iv, *ivlen)) {
/* SSLfatal() already called */
return 0;
}
if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) <= 0
|| (taglen != 0 && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG,
taglen, NULL) <= 0)
|| EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
if (sending) {
if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, *ivlen, NULL) <= 0
|| (mode == EVP_CIPH_CCM_MODE
&& EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, *taglen, NULL) <= 0)
|| EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
}
}
return 1;
@ -411,14 +422,14 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, int sending,
int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
{
#ifdef CHARSET_EBCDIC
static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
#else
static const unsigned char client_early_traffic[] = "c e traffic";
static const unsigned char client_handshake_traffic[] = "c hs traffic";
@ -437,7 +448,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
unsigned char *insecret;
unsigned char *finsecret = NULL;
const char *log_label = NULL;
EVP_CIPHER_CTX *ciph_ctx;
EVP_CIPHER_CTX *ciph_ctx = NULL;
size_t finsecretlen = 0;
const unsigned char *label;
size_t labellen, hashlen = 0;
@ -445,6 +456,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
const EVP_MD *md = NULL;
const EVP_CIPHER *cipher = NULL;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
size_t keylen, ivlen, taglen;
#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13)
ktls_crypto_info_t crypto_info;
void *rl_sequence;
@ -452,16 +464,6 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
#endif
if (which & SSL3_CC_READ) {
if (s->enc_read_ctx != NULL) {
EVP_CIPHER_CTX_reset(s->enc_read_ctx);
} else {
s->enc_read_ctx = EVP_CIPHER_CTX_new();
if (s->enc_read_ctx == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
goto err;
}
}
ciph_ctx = s->enc_read_ctx;
iv = s->read_iv;
RECORD_LAYER_reset_read_sequence(&s->rlayer);
@ -659,7 +661,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
insecret, hash, label, labellen, secret, key,
iv, ciph_ctx)) {
&keylen, iv, &ivlen, &taglen, ciph_ctx)) {
/* SSLfatal() already called */
goto err;
}
@ -700,6 +702,29 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS;
else
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
if ((which & SSL3_CC_READ) != 0) {
int level = (which & SSL3_CC_EARLY) != 0
? OSSL_RECORD_PROTECTION_LEVEL_EARLY
: ((which &SSL3_CC_HANDSHAKE) != 0
? OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE
: OSSL_RECORD_PROTECTION_LEVEL_APPLICATION);
s->rrlmethod->free(s->rrl);
s->rrl = s->rrlmethod->new_record_layer(sctx->libctx,
sctx->propq,
s->version, s->server,
OSSL_RECORD_DIRECTION_READ,
level, key, keylen, iv, ivlen,
NULL, 0, cipher, taglen,
NID_undef, NULL, NULL, s->rbio,
NULL, NULL, NULL, NULL, s);
if (s->rrl == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
}
#ifndef OPENSSL_NO_KTLS
# if defined(OPENSSL_KTLS_TLS13)
if (!(which & SSL3_CC_APPLICATION)
@ -776,7 +801,9 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
unsigned char *insecret, *iv;
unsigned char secret[EVP_MAX_MD_SIZE];
EVP_CIPHER_CTX *ciph_ctx;
size_t keylen, ivlen, taglen;
int ret = 0;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
if (s->server == sending)
insecret = s->server_app_traffic_secret;
@ -798,13 +825,32 @@ int tls13_update_key(SSL_CONNECTION *s, int sending)
s->s3.tmp.new_sym_enc, insecret, NULL,
application_traffic,
sizeof(application_traffic) - 1, secret, key,
iv, ciph_ctx)) {
&keylen, iv, &ivlen, &taglen, ciph_ctx)) {
/* SSLfatal() already called */
goto err;
}
memcpy(insecret, secret, hashlen);
if (!sending) {
s->rrlmethod->free(s->rrl);
s->rrl = s->rrlmethod->new_record_layer(sctx->libctx,
sctx->propq,
s->version, s->server,
OSSL_RECORD_DIRECTION_READ,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
key, keylen, iv, ivlen,
NULL, 0, s->s3.tmp.new_sym_enc,
taglen, NID_undef, NULL, NULL,
s->rbio, NULL, NULL, NULL, NULL,
s);
if (s->rrl == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
}
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
ret = 1;
err: