| 170 | #endif |
| 171 | |
| 172 | static int |
| 173 | tcp_signature_compute(struct mbuf *m, struct tcphdr *th, |
| 174 | struct secasvar *sav, u_char *buf) |
| 175 | { |
| 176 | MD5_CTX ctx; |
| 177 | int len; |
| 178 | u_short csum; |
| 179 | |
| 180 | MD5Init(&ctx); |
| 181 | /* Step 1: Update MD5 hash with IP(v6) pseudo-header. */ |
| 182 | switch (sav->sah->saidx.dst.sa.sa_family) { |
| 183 | #ifdef INET |
| 184 | case AF_INET: |
| 185 | len = ip_pseudo_compute(m, &ctx); |
| 186 | break; |
| 187 | #endif |
| 188 | #ifdef INET6 |
| 189 | case AF_INET6: |
| 190 | len = ip6_pseudo_compute(m, &ctx); |
| 191 | break; |
| 192 | #endif |
| 193 | default: |
| 194 | return (EAFNOSUPPORT); |
| 195 | } |
| 196 | /* |
| 197 | * Step 2: Update MD5 hash with TCP header, excluding options. |
| 198 | * The TCP checksum must be set to zero. |
| 199 | */ |
| 200 | csum = th->th_sum; |
| 201 | th->th_sum = 0; |
| 202 | MD5Update(&ctx, (char *)th, sizeof(struct tcphdr)); |
| 203 | th->th_sum = csum; |
| 204 | /* |
| 205 | * Step 3: Update MD5 hash with TCP segment data. |
| 206 | * Use m_apply() to avoid an early m_pullup(). |
| 207 | */ |
| 208 | len += (th->th_off << 2); |
| 209 | if (m->m_pkthdr.len - len > 0) |
| 210 | m_apply(m, len, m->m_pkthdr.len - len, |
| 211 | tcp_signature_apply, &ctx); |
| 212 | /* |
| 213 | * Step 4: Update MD5 hash with shared secret. |
| 214 | */ |
| 215 | MD5Update(&ctx, sav->key_auth->key_data, _KEYLEN(sav->key_auth)); |
| 216 | MD5Final(buf, &ctx); |
| 217 | key_sa_recordxfer(sav, m); |
| 218 | return (0); |
| 219 | } |
| 220 | |
| 221 | static void |
| 222 | setsockaddrs(const struct mbuf *m, union sockaddr_union *src, |
no test coverage detected