Blob Blame History Raw
diff --git a/print-esp.c b/print-esp.c
index 511ee8a3..5b282526 100644
--- a/print-esp.c
+++ b/print-esp.c
@@ -192,8 +192,8 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
 	const u_char *iv;
 	unsigned int len;
 	EVP_CIPHER_CTX *ctx;
-	unsigned int block_size, output_buffer_size;
-	u_char *output_buffer;
+	unsigned int block_size, buffer_size;
+	u_char *input_buffer, *output_buffer;
 
 	/* initiator arg is any non-zero value */
 	if(initiator) initiator=1;
@@ -228,19 +228,41 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
 		(*ndo->ndo_warning)(ndo, "espkey init failed");
 	set_cipher_parameters(ctx, NULL, NULL, iv, 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.
+	 * Allocate buffers for the encrypted and decrypted data.
+	 * Both buffers' sizes must be a multiple of the cipher block
+	 * size, and the output buffer must be separate from the input
+	 * buffer.
 	 */
 	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);
+	buffer_size = len + (block_size - len % block_size);
+
+	/*
+	 * Attempt to allocate the input buffer.
+	 */
+	input_buffer = (u_char *)malloc(buffer_size);
+	if (input_buffer == NULL) {
+		(*ndo->ndo_warning)(ndo, "can't allocate memory for encrypted data buffer");
+		EVP_CIPHER_CTX_free(ctx);
+		return 0;
+	}
+	/*
+	 * Copy the input data to the encrypted data buffer, and pad it
+	 * with zeroes.
+	 */
+	memcpy(input_buffer, buf, len);
+	memset(input_buffer + len, 0, buffer_size - len);
+
+	/*
+	 * Attempt to allocate the output buffer.
+	 */
+	output_buffer = (u_char *)malloc(buffer_size);
 	if (output_buffer == NULL) {
 		(*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+		free(input_buffer);
 		EVP_CIPHER_CTX_free(ctx);
 		return 0;
 	}
-	EVP_Cipher(ctx, output_buffer, buf, len);
+	EVP_Cipher(ctx, output_buffer, input_buffer, buffer_size);
 	EVP_CIPHER_CTX_free(ctx);
 
 	/*
@@ -249,6 +272,7 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
 	 * but changing this would require a more complicated fix.
 	 */
 	memcpy(buf, output_buffer, len);
+	free(input_buffer);
 	free(output_buffer);
 
 	ndo->ndo_packetp = buf;
@@ -666,8 +690,8 @@ esp_print(netdissect_options *ndo,
 	const u_char *ivoff;
 	const u_char *p;
 	EVP_CIPHER_CTX *ctx;
-	unsigned int block_size, output_buffer_size;
-	u_char *output_buffer;
+	unsigned int block_size, buffer_size;
+	u_char *input_buffer, *output_buffer;
 #endif
 
 	esp = (const struct newesp *)bp;
@@ -784,21 +808,43 @@ esp_print(netdissect_options *ndo,
 			len = ep - (p + ivlen);
 
 			/*
-			 * 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.
+			 * Allocate buffers for the encrypted and decrypted
+			 * data.  Both buffers' sizes must be a multiple of
+			 * the cipher block size, and the output buffer must
+			 * be separate from the input buffer.
 			 */
 			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);
+			buffer_size = len + (block_size - len % block_size);
+
+			/*
+			 * Attempt to allocate the input buffer.
+			 */
+			input_buffer = (u_char *)malloc(buffer_size);
+			if (input_buffer == NULL) {
+				(*ndo->ndo_warning)(ndo, "can't allocate memory for encrypted data buffer");
+				EVP_CIPHER_CTX_free(ctx);
+				return 0;
+			}
+			/*
+			 * Copy the input data to the encrypted data buffer,
+			 * and pad it with zeroes.
+			 */
+			memcpy(input_buffer, p + ivlen, len);
+			memset(input_buffer + len, 0, buffer_size - len);
+
+			/*
+			 * Attempt to allocate the output buffer.
+			 */
+			output_buffer = (u_char *)malloc(buffer_size);
 			if (output_buffer == NULL) {
 				(*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+				free(input_buffer);
 				EVP_CIPHER_CTX_free(ctx);
 				return -1;
 			}
 
-			EVP_Cipher(ctx, output_buffer, p + ivlen, len);
+			EVP_Cipher(ctx, output_buffer, input_buffer, len);
+			free(input_buffer);
 			EVP_CIPHER_CTX_free(ctx);
 			/*
 			 * XXX - of course this is wrong, because buf is a