+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ /*
+ * Failed to initialize the cipher context.
+ * From a look at the OpenSSL code, this appears to
+ * mean "couldn't allocate memory for the cipher context";
+ * note that we're not passing any parameters, so there's
+ * not much else it can mean.
+ */
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "esp_print: can't allocate memory for cipher context");
+ }
+
+ if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0) {
+ (*ndo->ndo_warning)(ndo, "espkey init failed");
+ return;
+ }
+
+ if (set_cipher_parameters(ctx, NULL, NULL, iv, 0) < 0) {
+ (*ndo->ndo_warning)(ndo, "IV init failed");
+ return;
+ }
+
+ /*
+ * 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);
+ buffer_size = ctlen + (block_size - ctlen % block_size);
+
+ /*
+ * Attempt to allocate the input buffer.
+ */
+ input_buffer = (u_char *)malloc(buffer_size);
+ if (input_buffer == NULL) {
+ EVP_CIPHER_CTX_free(ctx);
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "esp_print: can't allocate memory for encrypted data buffer");
+ }
+ /*
+ * Copy the input data to the encrypted data buffer,
+ * and pad it with zeroes.
+ */
+ memcpy(input_buffer, ct, ctlen);
+ memset(input_buffer + ctlen, 0, buffer_size - ctlen);
+
+ /*
+ * Attempt to allocate the output buffer.
+ */
+ output_buffer = (u_char *)malloc(buffer_size);
+ if (output_buffer == NULL) {
+ free(input_buffer);
+ EVP_CIPHER_CTX_free(ctx);
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "esp_print: can't allocate memory for decryption buffer");
+ }
+
+ if (!EVP_Cipher(ctx, output_buffer, input_buffer, ctlen)) {
+ free(input_buffer);
+ (*ndo->ndo_warning)(ndo, "EVP_Cipher failed");
+ return;
+ }
+ free(input_buffer);
+ EVP_CIPHER_CTX_free(ctx);
+
+ /*
+ * Pointer to the plaintext.
+ */
+ pt = output_buffer;
+
+ /*
+ * Length of the plaintext, which is the same as the length
+ * of the ciphertext.
+ */
+ ptlen = ctlen;