41#ifndef PROTOCORE_IKEV2_H
42#define PROTOCORE_IKEV2_H
52#define PC_IKEV2_PORT 500
54#define PC_IKEV2_NAT_PORT 4500
56#define PC_IKE_HDR_LEN 28
58#define PC_IKE_SPI_LEN 8
60#define PC_IKE_PAYLOAD_HDR_LEN 4
62#define PC_IKE_VERSION 0x20
64#define PC_IKE_CRITICAL 0x80
67#define PC_IKE_FLAG_INITIATOR 0x08
68#define PC_IKE_FLAG_VERSION 0x10
69#define PC_IKE_FLAG_RESPONSE 0x20
72enum class IkeExchange : uint8_t
76 IKE_CREATE_CHILD_SA = 36,
77 IKE_INFORMATIONAL = 37,
81enum class IkePayloadType : uint8_t
104enum class IkeTransformType : uint8_t
106 IKE_TRANSFORM_ENCR = 1,
107 IKE_TRANSFORM_PRF = 2,
108 IKE_TRANSFORM_INTEG = 3,
109 IKE_TRANSFORM_DH = 4,
110 IKE_TRANSFORM_ESN = 5,
114#define IKE_ENCR_AES_CBC 12
115#define IKE_ENCR_AES_GCM_16 20
116#define IKE_ENCR_CHACHA20_POLY1305 28
117#define IKE_PRF_HMAC_SHA2_256 5
118#define IKE_INTEG_HMAC_SHA2_256_128 12
119#define IKE_DH_MODP2048 14
120#define IKE_DH_ECP256 19
121#define IKE_DH_CURVE25519 31
124#define IKE_ATTR_KEY_LENGTH 14
127enum class IkeProtocol : uint8_t
136enum class IkeIdType : uint8_t
139 IKE_ID_IPV4_ADDR = 1,
141 IKE_ID_RFC822_ADDR = 3,
142 IKE_ID_IPV6_ADDR = 5,
147enum class IkeAuthMethod : uint8_t
149 IKE_AUTH_RESERVED = 0,
150 IKE_AUTH_RSA_SIG = 1,
152 IKE_AUTH_DSS_SIG = 3,
153 IKE_AUTH_DIGITAL_SIG = 14
157enum class IkeTsType : uint8_t
159 IKE_TS_IPV4_ADDR_RANGE = 7,
160 IKE_TS_IPV6_ADDR_RANGE = 8,
166 uint8_t init_spi[PC_IKE_SPI_LEN];
167 uint8_t resp_spi[PC_IKE_SPI_LEN];
168 IkePayloadType next_payload;
170 IkeExchange exchange;
181 IkePayloadType next_payload;
193 IkePayloadType next_type;
199 IkeTransformType type;
205struct IkeTransformRef
207 IkeTransformType type;
216 uint8_t proposal_num;
217 IkeProtocol protocol_id;
219 uint8_t num_transforms;
221 const uint8_t *transforms;
222 size_t transforms_len;
227struct IkeTransformIter
235struct IkeTrafficSelector
241 const uint8_t *start_addr;
242 const uint8_t *end_addr;
247enum class IkeCfgType : uint8_t
256#define PC_IKE_CFG_INTERNAL_IP4_ADDRESS 1
257#define PC_IKE_CFG_INTERNAL_IP4_NETMASK 2
258#define PC_IKE_CFG_INTERNAL_IP4_DNS 3
259#define PC_IKE_CFG_INTERNAL_IP4_NBNS 4
260#define PC_IKE_CFG_INTERNAL_IP4_DHCP 6
261#define PC_IKE_CFG_APPLICATION_VERSION 7
262#define PC_IKE_CFG_INTERNAL_IP6_ADDRESS 8
263#define PC_IKE_CFG_INTERNAL_IP6_DNS 10
264#define PC_IKE_CFG_INTERNAL_IP6_DHCP 12
265#define PC_IKE_CFG_INTERNAL_IP4_SUBNET 13
266#define PC_IKE_CFG_INTERNAL_IP6_SUBNET 15
272 const uint8_t *value;
291size_t pc_ike_hdr_build(uint8_t *buf,
size_t cap,
const IkeHeader *h);
298bool pc_ike_hdr_parse(
const uint8_t *buf,
size_t len, IkeHeader *out);
304bool pc_ike_set_length(uint8_t *buf,
size_t buf_cap, uint32_t total_len);
312void pc_ike_payload_iter_init(IkePayloadIter *it, IkePayloadType first_type,
const uint8_t *area,
size_t area_len);
319bool pc_ike_payload_next(IkePayloadIter *it, IkePayload *out);
326size_t pc_ike_payload_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload,
bool critical,
const uint8_t *body,
332size_t pc_ike_sa_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, uint8_t proposal_num,
333 IkeProtocol protocol_id,
const uint8_t *spi, uint8_t spi_size,
const IkeTransform *transforms,
334 uint8_t num_transforms);
337size_t pc_ike_ke_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, uint16_t dh_group,
const uint8_t *data,
341size_t pc_ike_nonce_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload,
const uint8_t *nonce,
345size_t pc_ike_id_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, IkeIdType id_type,
const uint8_t *data,
349size_t pc_ike_auth_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, IkeAuthMethod auth_method,
350 const uint8_t *data,
size_t data_len);
354size_t pc_ike_cert_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, uint8_t cert_encoding,
355 const uint8_t *data,
size_t data_len);
358size_t pc_ike_notify_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, IkeProtocol protocol_id,
359 const uint8_t *spi, uint8_t spi_size, uint16_t notify_type,
const uint8_t *data,
363size_t pc_ike_delete_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, IkeProtocol protocol_id,
364 uint8_t spi_size,
const uint8_t *spis, uint16_t num_spis);
367size_t pc_ike_ts_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload,
const IkeTrafficSelector *sels,
377size_t pc_ike_cp_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, IkeCfgType cfg_type,
378 const IkeCfgAttr *attrs, uint8_t num_attrs);
386size_t pc_ike_sk_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload,
const uint8_t *iv,
size_t iv_len,
387 const uint8_t *ciphertext,
size_t ct_len,
const uint8_t *icv,
size_t icv_len);
396#define PC_IKE_N_FRAGMENTATION_SUPPORTED 16430
398#define PC_IKE_FRAG_MAX 32
408size_t pc_ike_skf_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload, uint16_t frag_num, uint16_t total,
409 const uint8_t *iv,
size_t iv_len,
const uint8_t *ciphertext,
size_t ct_len,
const uint8_t *icv,
417bool pc_ike_skf_parse(
const uint8_t *body,
size_t body_len, uint16_t *frag_num, uint16_t *total,
size_t iv_len,
418 size_t icv_len,
const uint8_t **iv,
const uint8_t **ct,
size_t *ct_len,
const uint8_t **icv);
428 bool present[PC_IKE_FRAG_MAX];
429 size_t off[PC_IKE_FRAG_MAX];
430 size_t len[PC_IKE_FRAG_MAX];
437void pc_ike_frag_reasm_init(IkeFragReasm *r, uint8_t *pool,
size_t pool_cap);
444bool pc_ike_frag_reasm_add(IkeFragReasm *r, uint16_t frag_num, uint16_t total,
const uint8_t *chunk,
size_t len);
447bool pc_ike_frag_reasm_complete(
const IkeFragReasm *r);
453size_t pc_ike_frag_reasm_assemble(
const IkeFragReasm *r, uint8_t *out,
size_t out_cap);
464#define PC_IKE_N_COOKIE 16390
466#define PC_IKE_COOKIE_LEN 33
476size_t pc_ike_cookie_compute(uint8_t version,
const uint8_t *secret,
size_t secret_len,
const uint8_t *ni,
477 size_t ni_len,
const uint8_t *ipi,
size_t ipi_len,
const uint8_t spii[PC_IKE_SPI_LEN],
478 uint8_t *out,
size_t out_cap);
486bool pc_ike_cookie_verify(
const uint8_t *cookie,
size_t cookie_len,
const uint8_t *secret,
size_t secret_len,
487 const uint8_t *ni,
size_t ni_len,
const uint8_t *ipi,
size_t ipi_len,
488 const uint8_t spii[PC_IKE_SPI_LEN]);
491size_t pc_ike_cookie_notify_build(uint8_t *buf,
size_t cap, IkePayloadType next_payload,
const uint8_t *cookie,
497bool pc_ike_ke_parse(
const uint8_t *body,
size_t body_len, uint16_t *dh_group,
const uint8_t **data,
size_t *data_len);
500bool pc_ike_id_parse(
const uint8_t *body,
size_t body_len, IkeIdType *id_type,
const uint8_t **data,
size_t *data_len);
503bool pc_ike_auth_parse(
const uint8_t *body,
size_t body_len, IkeAuthMethod *auth_method,
const uint8_t **data,
507bool pc_ike_notify_parse(
const uint8_t *body,
size_t body_len, IkeProtocol *protocol_id, uint16_t *notify_type,
508 const uint8_t **spi, uint8_t *spi_size,
const uint8_t **data,
size_t *data_len);
511bool pc_ike_delete_parse(
const uint8_t *body,
size_t body_len, IkeProtocol *protocol_id, uint8_t *spi_size,
512 uint16_t *num_spis,
const uint8_t **spis);
518bool pc_ike_sk_parse(
const uint8_t *body,
size_t body_len,
size_t iv_len,
size_t icv_len,
const uint8_t **iv,
519 const uint8_t **ciphertext,
size_t *ct_len,
const uint8_t **icv);
524bool pc_ike_sa_first_proposal(
const uint8_t *body,
size_t body_len, IkeProposalRef *out);
527void pc_ike_transform_iter_init(IkeTransformIter *it,
const IkeProposalRef *p);
530bool pc_ike_transform_next(IkeTransformIter *it, IkeTransformRef *out);
535uint8_t pc_ike_ts_count(
const uint8_t *body,
size_t body_len);
538bool pc_ike_ts_get(
const uint8_t *body,
size_t body_len, uint8_t index, IkeTrafficSelector *out);
546bool pc_ike_cp_parse(
const uint8_t *body,
size_t body_len, IkeCfgType *cfg_type,
const uint8_t **attrs,
550void pc_ike_cp_attr_iter_init(IkeCfgAttrIter *it,
const uint8_t *attrs,
size_t attrs_len);
553bool pc_ike_cp_attr_next(IkeCfgAttrIter *it, IkeCfgAttr *out);
562#define PC_IKE_PRF_LEN 32
564#define PC_IKE_SK_MAX 40
566#define PC_IKE_NONCE_MAX 256
581 uint8_t sk_d[PC_IKE_SK_MAX];
582 uint8_t sk_ai[PC_IKE_SK_MAX];
583 uint8_t sk_ar[PC_IKE_SK_MAX];
584 uint8_t sk_ei[PC_IKE_SK_MAX];
585 uint8_t sk_er[PC_IKE_SK_MAX];
586 uint8_t sk_pi[PC_IKE_SK_MAX];
587 uint8_t sk_pr[PC_IKE_SK_MAX];
600bool pc_ike_prf_plus(
const uint8_t *key,
size_t key_len,
const uint8_t *seed,
size_t seed_len, uint8_t *out,
612bool pc_ike_derive_keys(
const uint8_t *dh_secret,
size_t dh_len,
const uint8_t *ni,
size_t ni_len,
const uint8_t *nr,
613 size_t nr_len,
const uint8_t *spi_i,
const uint8_t *spi_r,
const IkeKeyLengths *lens,
614 IkeKeyMaterial *out);
625#define PC_IKE_AEAD_KEY_LEN 32
627#define PC_IKE_GCM_SALT_LEN 4
629#define PC_IKE_GCM_IV_LEN 8
631#define PC_IKE_AEAD_ICV_LEN 16
640bool pc_ike_sk_aead_seal(
const uint8_t key[PC_IKE_AEAD_KEY_LEN],
const uint8_t salt[PC_IKE_GCM_SALT_LEN],
641 const uint8_t iv[PC_IKE_GCM_IV_LEN],
const uint8_t *aad,
size_t aad_len,
const uint8_t *pt,
642 size_t pt_len, uint8_t *out);
649bool pc_ike_sk_aead_open(
const uint8_t key[PC_IKE_AEAD_KEY_LEN],
const uint8_t salt[PC_IKE_GCM_SALT_LEN],
650 const uint8_t iv[PC_IKE_GCM_IV_LEN],
const uint8_t *aad,
size_t aad_len,
const uint8_t *ct,
651 size_t ct_len,
const uint8_t tag[PC_IKE_AEAD_ICV_LEN], uint8_t *out);
660#define PC_IKE_X25519_LEN 32
666size_t pc_ike_dh_public(uint16_t group,
const uint8_t *our_priv,
size_t priv_len, uint8_t *out,
size_t out_cap);
673size_t pc_ike_dh_compute(uint16_t group,
const uint8_t *our_priv,
size_t priv_len,
const uint8_t *peer_pub,
674 size_t pub_len, uint8_t *out,
size_t out_cap);
691#define PC_IKE_AUTH_LEN 32
693#define PC_IKE_PSK_PAD "Key Pad for IKEv2"
704bool pc_ike_auth_psk(
const uint8_t *psk,
size_t psk_len,
const uint8_t *real_msg,
size_t real_len,
705 const uint8_t *peer_nonce,
size_t nonce_len,
const uint8_t *sk_p,
size_t sk_p_len,
706 const uint8_t *id_body,
size_t id_body_len, uint8_t out[PC_IKE_AUTH_LEN]);
717 uint8_t init_spi[PC_IKE_SPI_LEN];
718 uint8_t resp_spi[PC_IKE_SPI_LEN];
720 IkeProposalRef proposal;
722 const uint8_t *ke_data;
724 const uint8_t *nonce;
739size_t pc_ike_sa_init_build(uint8_t *buf,
size_t cap,
const uint8_t init_spi[PC_IKE_SPI_LEN],
740 const uint8_t resp_spi[PC_IKE_SPI_LEN], uint32_t msg_id,
bool is_response,
741 uint8_t proposal_num,
const IkeTransform *transforms, uint8_t num_transforms,
742 uint16_t dh_group,
const uint8_t *ke_data,
size_t ke_len,
const uint8_t *nonce,
749bool pc_ike_sa_init_parse(
const uint8_t *msg,
size_t len, IkeSaInitMsg *out);
761#define PC_IKE_SK_OVERHEAD (PC_IKE_PAYLOAD_HDR_LEN + PC_IKE_GCM_IV_LEN + 1 + PC_IKE_AEAD_ICV_LEN)
770size_t pc_ike_auth_msg_build(uint8_t *buf,
size_t cap,
const uint8_t init_spi[PC_IKE_SPI_LEN],
771 const uint8_t resp_spi[PC_IKE_SPI_LEN], uint32_t msg_id,
bool is_response,
772 IkePayloadType first_inner_type,
const uint8_t *inner,
size_t inner_len,
773 const uint8_t key[PC_IKE_AEAD_KEY_LEN],
const uint8_t salt[PC_IKE_GCM_SALT_LEN],
774 const uint8_t iv[PC_IKE_GCM_IV_LEN]);
784bool pc_ike_auth_msg_open(uint8_t *msg,
size_t len,
const uint8_t key[PC_IKE_AEAD_KEY_LEN],
785 const uint8_t salt[PC_IKE_GCM_SALT_LEN], IkePayloadType *first_inner_type,
786 const uint8_t **inner_out,
size_t *inner_len_out);
796#define PC_IKE_ECDSA_P256_PUB_LEN 65
798#define PC_IKE_ECDSA_P256_PRIV_LEN 32
800#define PC_IKE_ECDSA_P256_SIG_LEN 64
807size_t pc_ike_signed_octets(uint8_t *scratch,
size_t cap,
const uint8_t *real,
size_t real_len,
const uint8_t *nonce,
808 size_t nonce_len,
const uint8_t *sk_p,
size_t sk_p_len,
const uint8_t *id_body,
815bool pc_ike_auth_sign_ecdsa_p256(uint8_t sig[PC_IKE_ECDSA_P256_SIG_LEN],
const uint8_t priv[PC_IKE_ECDSA_P256_PRIV_LEN],
816 uint8_t *scratch,
size_t scratch_cap,
const uint8_t *real,
size_t real_len,
817 const uint8_t *nonce,
size_t nonce_len,
const uint8_t *sk_p,
size_t sk_p_len,
818 const uint8_t *id_body,
size_t id_body_len);
824bool pc_ike_auth_verify_ecdsa_p256(
const uint8_t pub[PC_IKE_ECDSA_P256_PUB_LEN],
825 const uint8_t sig[PC_IKE_ECDSA_P256_SIG_LEN], uint8_t *scratch,
size_t scratch_cap,
826 const uint8_t *real,
size_t real_len,
const uint8_t *nonce,
size_t nonce_len,
827 const uint8_t *sk_p,
size_t sk_p_len,
const uint8_t *id_body,
size_t id_body_len);
849 uint8_t init_spi[PC_IKE_SPI_LEN];
850 uint8_t resp_spi[PC_IKE_SPI_LEN];
863bool pc_ike_suite_keylengths(
const IkeSuite *suite, IkeKeyLengths *out);
871bool pc_ike_sa_keys_from_init(IkeSa *sa,
const uint8_t *our_dh_priv,
size_t our_dh_priv_len,
const uint8_t *peer_ke,
872 size_t peer_ke_len,
const uint8_t *ni,
size_t ni_len,
const uint8_t *nr,
size_t nr_len);
882bool pc_ike_rekey_derive_keys(
const uint8_t *sk_d_old,
size_t sk_d_old_len,
const uint8_t *dh_secret,
size_t dh_len,
883 const uint8_t *ni,
size_t ni_len,
const uint8_t *nr,
size_t nr_len,
const uint8_t *spi_i,
884 const uint8_t *spi_r,
const IkeKeyLengths *lens, IkeKeyMaterial *out);
896#define PC_IKE_MSG_MAX 640
898enum class IkeState : uint8_t
913 uint8_t our_dh_priv[PC_IKE_X25519_LEN];
914 uint8_t our_nonce[PC_IKE_NONCE_MAX];
915 uint16_t our_nonce_len;
916 uint8_t peer_nonce[PC_IKE_NONCE_MAX];
917 uint16_t peer_nonce_len;
918 uint8_t init_msg[PC_IKE_MSG_MAX];
919 uint16_t init_msg_len;
920 uint8_t resp_msg[PC_IKE_MSG_MAX];
921 uint16_t resp_msg_len;
932size_t pc_ike_initiator_start(IkeHandshake *hs,
const uint8_t our_spi[PC_IKE_SPI_LEN],
933 const uint8_t our_dh_priv[PC_IKE_X25519_LEN],
const uint8_t our_dh_pub[PC_IKE_X25519_LEN],
934 const uint8_t *our_nonce,
size_t nonce_len,
const IkeSuite *suite,
935 const IkeTransform *transforms, uint8_t num_transforms, uint8_t *out,
size_t out_cap);
944bool pc_ike_initiator_on_sa_init(IkeHandshake *hs,
const uint8_t *resp,
size_t resp_len);
955size_t pc_ike_initiator_build_auth_psk(IkeHandshake *hs, IkeIdType idi_type,
const uint8_t *idi_data,
size_t idi_len,
956 const uint8_t *psk,
size_t psk_len,
const uint8_t iv[PC_IKE_GCM_IV_LEN],
957 uint8_t *out,
size_t out_cap);
966bool pc_ike_initiator_on_auth_psk(IkeHandshake *hs,
const uint8_t *resp,
size_t resp_len,
const uint8_t *psk,
985size_t pc_ike_responder_on_sa_init(IkeHandshake *hs,
const uint8_t *req,
size_t req_len,
986 const uint8_t our_spi[PC_IKE_SPI_LEN],
const uint8_t our_dh_priv[PC_IKE_X25519_LEN],
987 const uint8_t our_dh_pub[PC_IKE_X25519_LEN],
const uint8_t *our_nonce,
988 size_t nonce_len,
const IkeSuite *suite,
const IkeTransform *transforms,
989 uint8_t num_transforms, uint8_t *out,
size_t out_cap);
1000size_t pc_ike_responder_on_auth_psk(IkeHandshake *hs,
const uint8_t *req,
size_t req_len,
const uint8_t *psk,
1001 size_t psk_len, IkeIdType idr_type,
const uint8_t *idr_data,
size_t idr_len,
1002 const uint8_t iv[PC_IKE_GCM_IV_LEN], uint8_t *out,
size_t out_cap);
1015size_t pc_ike_informational_build(
const IkeSa *sa,
bool is_response, uint32_t msg_id, IkePayloadType first_inner_type,
1016 const uint8_t *inner,
size_t inner_len,
const uint8_t iv[PC_IKE_GCM_IV_LEN],
1017 uint8_t *out,
size_t out_cap);
1023bool pc_ike_informational_open(
const IkeSa *sa, uint8_t *msg,
size_t len, IkePayloadType *first_inner_type,
1024 const uint8_t **inner_out,
size_t *inner_len_out);
1033size_t pc_ike_create_child_sa_build(
const IkeSa *sa,
bool is_response, uint32_t msg_id, IkePayloadType first_inner_type,
1034 const uint8_t *inner,
size_t inner_len,
const uint8_t iv[PC_IKE_GCM_IV_LEN],
1035 uint8_t *out,
size_t out_cap);
1044bool pc_ike_child_keymat(
const uint8_t *sk_d,
size_t sk_d_len,
const uint8_t *dh_secret,
size_t dh_len,
1045 const uint8_t *ni,
size_t ni_len,
const uint8_t *nr,
size_t nr_len, uint8_t *out,
1056bool pc_ike_auth_verify_rsa_sha256(
const uint8_t *n_be,
const uint8_t *e_be4,
const uint8_t *sig,
size_t sig_len,
1057 uint8_t *scratch,
size_t scratch_cap,
const uint8_t *real,
size_t real_len,
1058 const uint8_t *nonce,
size_t nonce_len,
const uint8_t *sk_p,
size_t sk_p_len,
1059 const uint8_t *id_body,
size_t id_body_len);
User-facing configuration for ProtoCore.