@@ -429,7 +429,6 @@ static int esp_unwrap(struct wolfIP *s, struct wolfIP_ip_packet *ip,
429429 pad_len = * (ip -> data + esp_len - esp_sa -> icv_len - ESP_NEXT_HEADER_LEN
430430 - ESP_PADDING_LEN );
431431 nxt_hdr = * (ip -> data + esp_len - esp_sa -> icv_len - ESP_NEXT_HEADER_LEN );
432- ip -> proto = nxt_hdr ;
433432
434433 #ifdef WOLFIP_DEBUG_ESP
435434 wolfIP_print_esp (esp_sa , ip -> data , esp_len , pad_len , nxt_hdr );
@@ -452,7 +451,12 @@ static int esp_unwrap(struct wolfIP *s, struct wolfIP_ip_packet *ip,
452451 ESP_NEXT_HEADER_LEN + esp_sa -> icv_len );
453452 ip -> len = ip -> len - (pad_len + ESP_PADDING_LEN +
454453 ESP_NEXT_HEADER_LEN + esp_sa -> icv_len );
454+
455+ /* update len, set proto to next header, recalculate iphdr checksum. */
455456 ip -> len = ee16 (ip -> len );
457+ ip -> proto = nxt_hdr ;
458+ ip -> csum = 0 ;
459+ iphdr_set_checksum (ip );
456460
457461 #ifdef WOLFIP_DEBUG_ESP_VERBOSE
458462 esp_dump_data_verbose ("esp_packet after unwrap" , ip -> data ,
@@ -608,4 +612,48 @@ static int esp_wrap(struct wolfIP_ip_packet *ip, uint16_t * ip_len)
608612
609613 return 0 ;
610614}
615+
616+ /**
617+ * Copy frame to new packet so we can expand and wrap in place
618+ * without stepping on the fifo tcp circular buffer.
619+ * */
620+ static int esp_output (struct wolfIP * s , const struct wolfIP_ip_packet * ip ,
621+ uint16_t len )
622+ {
623+ /**
624+ * 56 is reasonable max ESP overhead (for now), rounded up to 4 bytes.
625+ * 8 bytes (esp header)
626+ * + 16 bytes (iv, prepended to payload)
627+ * + 15 bytes (max padding with block cipher)
628+ * + 2 bytes (pad_len + nxt_hdr fields)
629+ * + 12 bytes (icv)
630+ * may need to increase depending on algs supported.
631+ * */
632+ struct wolfIP_ip_packet * esp ;
633+ uint8_t frame [LINK_MTU + 56 ];
634+ uint16_t ip_final_len = len ;
635+ int esp_rc = 0 ;
636+
637+ esp = (struct wolfIP_ip_packet * ) frame ;
638+ memcpy (esp , ip , sizeof (struct wolfIP_ip_packet ) + len );
639+
640+ esp_rc = esp_wrap (esp , & ip_final_len );
641+
642+ if (esp_rc ) {
643+ #ifdef WOLFIP_DEBUG_ESP
644+ printf ("error: esp_wrap returned: %d\n" , esp_rc );
645+ #endif /* WOLFIP_DEBUG_ESP */
646+ return esp_rc ;
647+ }
648+
649+ /* update len, set proto to ESP 0x32 (50), recalculate iphdr checksum. */
650+ esp -> len = ee16 (ip_final_len );
651+ esp -> proto = 0x32 ;
652+ esp -> csum = 0 ;
653+ iphdr_set_checksum (esp );
654+
655+ s -> ll_dev .send (& s -> ll_dev , esp , ip_final_len + ETH_HEADER_LEN );
656+
657+ return 0 ;
658+ }
611659#endif /* WOLFIP_ESP && !WOLFESP_SRC */
0 commit comments