Attempt to allocate the buffer before doing any decryption calls and, if
the attempt fails, report an error and return an error indication.
Make sizes unsigned, as they can't be negative;
EVP_CIPHER_CTX_block_size() returns an int, but that's just because they
picked the wrong data type in OpenSSL.
No need to use calloc() for the output buffer - just use malloc().
{
struct sa_list *sa;
const u_char *iv;
{
struct sa_list *sa;
const u_char *iv;
- u_char *output_buffer;
- int len, block_size, output_buffer_size;
+ unsigned int block_size, output_buffer_size;
+ u_char *output_buffer;
/* initiator arg is any non-zero value */
if(initiator) initiator=1;
/* initiator arg is any non-zero value */
if(initiator) initiator=1;
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
return 0;
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
return 0;
+ /*
+ * Allocate a buffer for the decrypted data.
+ * The output buffer must be separate from the input buffer, and
+ * its size must be a multiple of the cipher block size.
+ */
+ block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
+ output_buffer_size = len + (block_size - len % block_size);
+ output_buffer = (u_char *)malloc(output_buffer_size);
+ if (output_buffer == NULL) {
+ (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ return 0;
+ }
if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
EVP_CipherInit(ctx, NULL, NULL, iv, 0);
if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
EVP_CipherInit(ctx, NULL, NULL, iv, 0);
-
- /* We need a block size */
- block_size = EVP_CIPHER_CTX_block_size(ctx);
- /* We need the buffer size to be multiple of a block size */
- output_buffer_size = len + (block_size - len % block_size);
- output_buffer = (u_char *)calloc(output_buffer_size, sizeof(u_char));
- /* EVP_Cipher output buffer should be different from the input one.
- * Also it should be of size that is multiple of cipher block size. */
EVP_Cipher(ctx, output_buffer, buf, len);
EVP_CIPHER_CTX_free(ctx);
EVP_Cipher(ctx, output_buffer, buf, len);
EVP_CIPHER_CTX_free(ctx);
ndo->ndo_snapend = end;
return 1;
ndo->ndo_snapend = end;
return 1;
const u_char *ivoff;
const u_char *p;
EVP_CIPHER_CTX *ctx;
const u_char *ivoff;
const u_char *p;
EVP_CIPHER_CTX *ctx;
+ unsigned int block_size, output_buffer_size;
- int block_size, output_buffer_size;
#endif
esp = (const struct newesp *)bp;
#endif
esp = (const struct newesp *)bp;
+ /* pointer to the IV, if there is one */
ivoff = (const u_char *)(esp + 1) + 0;
ivoff = (const u_char *)(esp + 1) + 0;
+ /* length of the IV, if there is one; 0, if there isn't */
ivlen = sa->ivlen;
secret = sa->secret;
ep = ep - sa->authlen;
ivlen = sa->ivlen;
secret = sa->secret;
ep = ep - sa->authlen;
if (sa->evp) {
ctx = EVP_CIPHER_CTX_new();
if (ctx != NULL) {
if (sa->evp) {
ctx = EVP_CIPHER_CTX_new();
if (ctx != NULL) {
+ /*
+ * Allocate a buffer for the decrypted data.
+ * The output buffer must be separate from the
+ * input buffer, and its size must be a multiple
+ * of the cipher block size.
+ */
+ block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
+ output_buffer_size = len + (block_size - len % block_size);
+ output_buffer = (u_char *)malloc(output_buffer_size);
+ if (output_buffer == NULL) {
+ (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ return -1;
+ }
+
if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
EVP_CipherInit(ctx, NULL, NULL, p, 0);
len = ep - (p + ivlen);
EVP_CipherInit(ctx, NULL, NULL, p, 0);
len = ep - (p + ivlen);
- /* We need a block size */
- block_size = EVP_CIPHER_CTX_block_size(ctx);
- /* We need the buffer size to be multiple of a block size */
- output_buffer_size = len + (block_size - len % block_size);
- output_buffer = (u_char *)calloc(output_buffer_size, sizeof(u_char));
- /* EVP_Cipher output buffer should be different from the input one.
- * Also it should be of size that is multiple of cipher block size. */
EVP_Cipher(ctx, output_buffer, p + ivlen, len);
EVP_CIPHER_CTX_free(ctx);
/*
EVP_Cipher(ctx, output_buffer, p + ivlen, len);
EVP_CIPHER_CTX_free(ctx);
/*