/* * compute ESP header size. */ size_t esp_hdrsiz(struct ipsecrequest *isr) { struct secasvar *sav; const struct esp_algorithm *algo; const struct ah_algorithm *aalgo; size_t ivlen; size_t authlen; size_t hdrsiz; /* sanity check */ if (isr == NULL) panic("esp_hdrsiz: NULL was passed."); sav = isr->sav; if (isr->saidx.proto != IPPROTO_ESP) panic("unsupported mode passed to esp_hdrsiz"); if (sav == NULL) goto estimate; if (sav->state != SADB_SASTATE_MATURE && sav->state != SADB_SASTATE_DYING) goto estimate; /* we need transport mode ESP. */ algo = esp_algorithm_lookup(sav->alg_enc); if (!algo) goto estimate; ivlen = sav->ivlen; if (ivlen < 0) goto estimate; /* * XXX * right now we don't calcurate the padding size. simply * treat the padding size as constant, for simplicity. * * XXX variable size padding support */ if (sav->flags & SADB_X_EXT_OLD) { /* RFC 1827 */ hdrsiz = sizeof(struct esp) + ivlen + 9; } else { /* RFC 2406 */ aalgo = ah_algorithm_lookup(sav->alg_auth); if (aalgo && sav->replay && sav->key_auth) authlen = (aalgo->sumsiz)(sav); else authlen = 0; hdrsiz = sizeof(struct newesp) + ivlen + 9 + authlen; } return hdrsiz; estimate: /* * ASSUMING: * sizeof(struct newesp) > sizeof(struct esp). * esp_max_ivlen() = max ivlen for CBC mode * 9 = (maximum padding length without random padding length) * + (Pad Length field) + (Next Header field). * 16 = maximum ICV we support. */ return sizeof(struct newesp) + esp_max_ivlen() + 9 + 16; }
/* * compute ESP header size. */ size_t esp_hdrsiz(__unused struct ipsecrequest *isr) { #if 0 /* sanity check */ if (isr == NULL) panic("esp_hdrsiz: NULL was passed.\n"); lck_mtx_lock(sadb_mutex); { struct secasvar *sav; const struct esp_algorithm *algo; const struct ah_algorithm *aalgo; size_t ivlen; size_t authlen; size_t hdrsiz; size_t maxpad; /*%%%% this needs to change - no sav in ipsecrequest any more */ sav = isr->sav; if (isr->saidx.proto != IPPROTO_ESP) panic("unsupported mode passed to esp_hdrsiz"); if (sav == NULL) goto estimate; if (sav->state != SADB_SASTATE_MATURE && sav->state != SADB_SASTATE_DYING) goto estimate; /* we need transport mode ESP. */ algo = esp_algorithm_lookup(sav->alg_enc); if (!algo) goto estimate; ivlen = sav->ivlen; if (ivlen < 0) goto estimate; if (algo->padbound) maxpad = algo->padbound; else maxpad = 4; maxpad += 1; /* maximum 'extendsiz' is padbound + 1, see esp_output */ if (sav->flags & SADB_X_EXT_OLD) { /* RFC 1827 */ hdrsiz = sizeof(struct esp) + ivlen + maxpad; } else { /* RFC 2406 */ aalgo = ah_algorithm_lookup(sav->alg_auth); if (aalgo && sav->replay && sav->key_auth) authlen = (aalgo->sumsiz)(sav); else authlen = 0; hdrsiz = sizeof(struct newesp) + ivlen + maxpad + authlen; } /* * If the security association indicates that NATT is required, * add the size of the NATT encapsulation header: */ if ((sav->flags & SADB_X_EXT_NATT) != 0) hdrsiz += sizeof(struct udphdr) + 4; lck_mtx_unlock(sadb_mutex); return hdrsiz; } estimate: lck_mtx_unlock(sadb_mutex); #endif /* * ASSUMING: * sizeof(struct newesp) > sizeof(struct esp). (8) * esp_max_ivlen() = max ivlen for CBC mode * 17 = (maximum padding length without random padding length) * + (Pad Length field) + (Next Header field). * 64 = maximum ICV we support. * sizeof(struct udphdr) in case NAT traversal is used */ return sizeof(struct newesp) + esp_max_ivlen() + 17 + AH_MAXSUMSIZE + sizeof(struct udphdr); }