#include "internal/evp_int.h"
#include "modes_lcl.h"
#include <openssl/rand.h>
+#include "evp_locl.h"
typedef struct {
union {
static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
{
EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,c);
+ if (gctx == NULL)
+ return 0;
OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c))
OPENSSL_free(gctx->iv);
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
| EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
/* Correct length for explicit IV */
+ if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN)
+ return 0;
len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
/* If decrypting correct for tag too */
- if (!EVP_CIPHER_CTX_encrypting(c))
+ if (!EVP_CIPHER_CTX_encrypting(c)) {
+ if (len < EVP_GCM_TLS_TAG_LEN)
+ return 0;
len -= EVP_GCM_TLS_TAG_LEN;
+ }
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
}
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
| EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
/* Correct length for explicit IV */
+ if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN)
+ return 0;
len -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
/* If decrypting correct for tag too */
- if (!EVP_CIPHER_CTX_encrypting(c))
+ if (!EVP_CIPHER_CTX_encrypting(c)) {
+ if (len < cctx->M)
+ return 0;
len -= cctx->M;
+ }
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
}
case EVP_CTRL_AEAD_SET_IVLEN:
arg = 15 - arg;
+ /* fall thru */
case EVP_CTRL_CCM_SET_L:
if (arg < 2 || arg > 8)
return 0;
if (cctx->tls_aad_len >= 0)
return aes_ccm_tls_cipher(ctx, out, in, len);
+ /* EVP_*Final() doesn't return any data */
+ if (in == NULL && out != NULL)
+ return 0;
+
if (!cctx->iv_set)
return -1;
CRYPTO_ccm128_aad(ccm, in, len);
return len;
}
- /* EVP_*Final() doesn't return any data */
- if (!in)
- return 0;
/* If not set length yet do it */
if (!cctx->len_set) {
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
/* If not padding input must be multiple of 8 */
if (!pad && inlen & 0x7)
return -1;
+ if (is_partially_overlapping(out, in, inlen)) {
+ EVPerr(EVP_F_AES_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
+ return 0;
+ }
if (!out) {
if (EVP_CIPHER_CTX_encrypting(ctx)) {
/* If padding round up to multiple of 8 */
} else {
buf = octx->data_buf;
buf_len = &(octx->data_buf_len);
+
+ if (is_partially_overlapping(out + *buf_len, in, len)) {
+ EVPerr(EVP_F_AES_OCB_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
+ return 0;
+ }
}
/*