// Generate auth message S3 static void authGenS3(struct s_auth_state *authstate) { // generate msg(remote_authid, msgnum, enc(keygen_nonce, local_seq, local_peerid, local_flags)) unsigned char unencrypted_nextmsg[auth_MAXMSGSIZE_S3]; int unencrypted_nextmsg_size = (4 + 2 + auth_NONCESIZE + seq_SIZE + 4 + 8); int msgnum = authstate->state; int encsize; if(authstate->local_cneg_set) { memcpy(unencrypted_nextmsg, authstate->remote_authid, 4); utilWriteInt16(&unencrypted_nextmsg[4], msgnum); memcpy(authstate->nextmsg, unencrypted_nextmsg, 6); memcpy(&unencrypted_nextmsg[(4 + 2)], authstate->local_keygen_nonce, auth_NONCESIZE); memcpy(&unencrypted_nextmsg[(4 + 2 + auth_NONCESIZE)], authstate->local_seq, seq_SIZE); utilWriteInt32(&unencrypted_nextmsg[(4 + 2 + auth_NONCESIZE + seq_SIZE)], authstate->local_peerid); memcpy(&unencrypted_nextmsg[(4 + 2 + auth_NONCESIZE + seq_SIZE + 4)], authstate->local_flags, 8); encsize = cryptoEnc(&authstate->crypto_ctx[auth_CRYPTOCTX_CNEG], &authstate->nextmsg[(4 + 2)], (auth_MAXMSGSIZE - 2 - 4), &unencrypted_nextmsg[(4 + 2)], (unencrypted_nextmsg_size - 2 - 4), auth_CNEGHMACSIZE, auth_CNEGIVSIZE); if(encsize > 0) { authstate->nextmsg_size = (encsize + 4 + 2); } else { authstate->nextmsg_size = 0; } } else { authstate->nextmsg_size = 0; } }
// encode packet static int packetEncode(unsigned char *pbuf, const int pbuf_size, const struct s_packet_data *data, struct s_crypto *ctx) { unsigned char dec_buf[packet_CRHDR_SIZE + data->pl_buf_size]; int32_t *scr_peerid = ((int32_t *)pbuf); int32_t ne_peerid; int len; // check if enough space is available for the operation if(data->pl_length > data->pl_buf_size) { return 0; } // prepare buffer utilWriteInt64(&dec_buf[packet_CRHDR_SEQ_START], data->seq); utilWriteInt16(&dec_buf[packet_CRHDR_PLLEN_START], data->pl_length); dec_buf[packet_CRHDR_PLTYPE_START] = data->pl_type; dec_buf[packet_CRHDR_PLOPT_START] = data->pl_options; memcpy(&dec_buf[packet_CRHDR_SIZE], data->pl_buf, data->pl_length); // encrypt buffer len = cryptoEnc(ctx, &pbuf[packet_PEERID_SIZE], (pbuf_size - packet_PEERID_SIZE), dec_buf, (packet_CRHDR_SIZE + data->pl_length), packet_HMAC_SIZE, packet_IV_SIZE); if(len < (packet_HMAC_SIZE + packet_IV_SIZE + packet_CRHDR_SIZE)) { return 0; } // write the scrambled peer ID utilWriteInt32((unsigned char *)&ne_peerid, data->peerid); scr_peerid[0] = (ne_peerid ^ (scr_peerid[1] ^ scr_peerid[2])); // return length of encoded packet return (packet_PEERID_SIZE + len); }
// Generate auth message S2 static void authGenS2(struct s_auth_state *authstate) { // generate msg(remote_authid, msgnum, enc(pubkey_len, pubkey, sig_len, sig(authid, msgnum, local_nonce, remote_nonce, remote_dhkey, local_dhkey), hmac(pubkey))) unsigned char unencrypted_nextmsg[auth_MAXMSGSIZE_S2]; int unencrypted_nextmsg_size; int msgnum = authstate->state; unsigned char siginbuf[auth_SIGINBUFSIZE]; struct s_nodekey *local_nodekey; struct s_rsa *rsakey; int siginbuf_size; int nksize; int signsize; int encsize; memcpy(unencrypted_nextmsg, authstate->remote_authid, 4); utilWriteInt16(&unencrypted_nextmsg[4], msgnum); memcpy(authstate->nextmsg, unencrypted_nextmsg, 6); siginbuf_size = authGenSigIn(authstate, siginbuf, &unencrypted_nextmsg[4]); local_nodekey = authstate->local_nodekey; nksize = nodekeyGetDER(&unencrypted_nextmsg[(4 + 2 + 2)], nodekey_MAXSIZE, local_nodekey); if(nksize > nodekey_MINSIZE) { utilWriteInt16(&unencrypted_nextmsg[(4 + 2)], nksize); rsakey = &local_nodekey->key; signsize = rsaSign(rsakey, &unencrypted_nextmsg[(4 + 2 + 2 + nksize + 2)], nodekey_MAXSIZE, siginbuf, siginbuf_size); if(signsize > 0) { utilWriteInt16(&unencrypted_nextmsg[(4 + 2 + 2 + nksize)], signsize); if(cryptoHMAC(&authstate->crypto_ctx[auth_CRYPTOCTX_AUTH], &unencrypted_nextmsg[(4 + 2 + 2 + nksize + 2 + signsize)], auth_HMACSIZE, &unencrypted_nextmsg[(4 + 2 + 2)], nksize)) { unencrypted_nextmsg_size = (4 + 2 + 2 + nksize + 2 + signsize + auth_HMACSIZE); encsize = cryptoEnc(&authstate->crypto_ctx[auth_CRYPTOCTX_IDP], &authstate->nextmsg[(4 + 2)], (auth_MAXMSGSIZE - 2 - 4), &unencrypted_nextmsg[(2 + 4)], (unencrypted_nextmsg_size - 2 - 4), auth_IDPHMACSIZE, auth_IDPIVSIZE); if(encsize > 0) { authstate->nextmsg_size = (encsize + 4 + 2); } else { authstate->nextmsg_size = 0; } } else { authstate->nextmsg_size = 0; } } else { authstate->nextmsg_size = 0; } } else { authstate->nextmsg_size = 0; } }