protocol/crypto.c File Reference

#include "crypto.h"

Include dependency graph for crypto.c:

Go to the source code of this file.

Defines

#define bSecureDestroy(b)

Functions

int CryptState_create_key (CryptState *state)
int CryptState_create_shared_key (CryptState *state, Node *header, int nonced, CryptState_key_confirm_cb key_confirm)
int CryptState_finalize_session (CryptState *state)
int CryptState_init ()
void CryptState_peer_destroy (CryptState *state, crypt_key_side my_key)
void CryptState_destroy (CryptState *state)
void CryptState_rand_sess (CryptState *state)
CryptStateCryptState_create (bstring name, bstring prvkey)
void CryptState_reset (CryptState *state)
int CryptState_rand (void *data, size_t len)
int CryptState_create_nonce (CryptNonce *nonce)
bstring CryptState_export_key (CryptState *state, crypt_key_side my_key, int type)
int CryptState_import_key (CryptState *state, crypt_key_side my_key, bstring from)
NodeCryptState_receiver_start (CryptState *state)
int CryptState_receiver_process_response (CryptState *state, bstring hbuf, Node *payload, CryptState_key_confirm_cb key_confirm)
NodeCryptState_receiver_send_final (CryptState *state, bstring *hbuf)
int CryptState_receiver_done (CryptState *state, bstring header, Node *msg)
NodeCryptState_initiator_start (CryptState *state, Node *recvhdr, bstring *hbuf, CryptState_key_confirm_cb key_confirm)
int CryptState_initiator_process_response (CryptState *state, bstring header, Node *msg)
NodeCryptState_initiator_send_final (CryptState *state, bstring *hbuf)
NodeCryptState_encrypt_packet (CryptState *state, symmetric_key *key, bstring header, bstring payload)
NodeCryptState_encrypt_node (CryptState *state, symmetric_key *key, bstring header, Node *payload)
bstring CryptState_decrypt_packet (CryptState *state, symmetric_key *key, bstring header, Node *packet)
NodeCryptState_decrypt_node (CryptState *state, symmetric_key *key, bstring header, Node *packet)
void CryptState_print_key (CryptState *state, crypt_key_side my_key, int type)
bstring CryptState_fingerprint_key (CryptState *state, crypt_key_side my_key, int type)
bstring CryptState_fingerprint_bstr (bstring str)
bstring CryptState_hash_nonce (CryptNonce *nonce)
NodeCryptState_generate_hate_challenge (CryptState *state, unsigned int level, unsigned long long *expecting)
NodeCryptState_answer_hate_challenge (CryptState *state, Node *challenge, int *sig_stat, unsigned int max_allowed_level)
int CryptState_validate_hate_challenge (CryptState *state, Node *challenge, Node *answer, unsigned long long expecting)

Variables

ltc_math_descriptor ltc_mp
static prng_state global_prng
static int global_hash_idx
static int global_prng_idx
static int global_cipher_idx
static int CryptState_initialized = 0


Define Documentation

#define bSecureDestroy (  ) 

Value:

{                                               \
bstring bstr__tmp = (b);                                                \
    if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) {          \
        (void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen);   \
        bdestroy (bstr__tmp);                                           \
    }                                                                   \
}
Taken from bstraux.h and used to wipe memory before freeing it.

Definition at line 21 of file crypto.c.

Referenced by CryptState_decrypt_packet(), CryptState_encrypt_node(), CryptState_export_key(), CryptState_finalize_session(), CryptState_initiator_process_response(), CryptState_peer_destroy(), and CryptState_print_key().


Function Documentation

Node* CryptState_answer_hate_challenge ( CryptState state,
Node challenge,
int *  sig_stat,
unsigned int  max_allowed_level 
)

Definition at line 762 of file crypto.c.

References assert_not, balloc(), bdata, bdestroy(), bisstemeqblk(), blength, blk2bstr(), bsetsize, check, CRYPT_ANSWER_MSG, CRYPT_CHALLENGE_MSG, CryptState_hash_nonce(), CryptState_nonce_set, ensure, global_hash_idx, global_prng, global_prng_idx, CryptPeer::key, CryptNonce::left, ltc_ok, CryptState::me, Node_cons(), Node_decons(), NONCE_LENGTH, CryptNonce::num, CryptNonce::raw, CryptNonce::right, and CryptState::them.

Here is the call graph for this function:

CryptState* CryptState_create ( bstring  name,
bstring  prvkey 
)

Creates a new CryptState that you can use with the remaining functions to establish a secure connection and transmit/receive encrypted packets.

If prvkey is NULL then a new key will be generated for you. You can then use crypt_export_key to save the key for later.

Definition at line 120 of file crypto.c.

References assert_mem, assert_not, bstrcpy(), check, CRYPT_MY_KEY, CryptState_create_key(), CryptState_import_key(), CryptState_rand_sess(), ensure, CryptState::me, and CryptPeer::name.

Referenced by ConnectionState_exec(), Hub_exec(), and Proxy_connect().

Here is the call graph for this function:

int CryptState_create_key ( CryptState state  )  [inline]

Definition at line 180 of file crypto.c.

References assert_not, global_prng, global_prng_idx, CryptPeer::key, KEY_LENGTH, ltc_ok, CryptState::me, and on_fail.

Referenced by CryptState_create().

int CryptState_create_nonce ( CryptNonce nonce  ) 

Fills the given nonce with randomness so you can use it.

Definition at line 174 of file crypto.c.

References assert_not, CryptState_rand(), NONCE_LENGTH, and CryptNonce::raw.

Referenced by CryptState_generate_hate_challenge(), CryptState_initiator_start(), CryptState_receiver_send_final(), and CryptState_receiver_start().

Here is the call graph for this function:

int CryptState_create_shared_key ( CryptState state,
Node header,
int  nonced,
CryptState_key_confirm_cb  key_confirm 
) [inline]

Definition at line 236 of file crypto.c.

References assert_not, blength, check, CRYPT_HEADER, CRYPT_THEIR_KEY, CryptState_import_key(), CryptState_nonce_set, CryptPeer::key, ltc_ok, CryptState::me, Node_decons(), CryptPeer::nonce, NONCE_LENGTH, on_fail, CryptState::shared, and CryptState::them.

Referenced by CryptState_initiator_start(), and CryptState_receiver_process_response().

Here is the call graph for this function:

Node* CryptState_decrypt_node ( CryptState state,
symmetric_key *  key,
bstring  header,
Node packet 
)

Again the inverse of CryptState_encrypt_node() this takes the encrypted packet and then decrypts it and converts it directly to a Node using Node_parse().

Definition at line 615 of file crypto.c.

References assert_not, blength, check, check_then, CryptState_decrypt_packet(), tagbstring::data, ensure, and Node_parse().

Referenced by CryptState_initiator_process_response(), CryptState_receiver_done(), CryptState_receiver_process_response(), Peer_recv(), and Proxy_hub_recv().

Here is the call graph for this function:

bstring CryptState_decrypt_packet ( CryptState state,
symmetric_key *  key,
bstring  header,
Node packet 
)

The inverse of CryptState_encrypt_packet() taking the Node and decrypting it (again, in place) to extract the original bstring payload. The returned payload is not copied so you just Node_destroy(packet) to free it.

Definition at line 580 of file crypto.c.

References assert_not, bdata, bdestroy(), bfromcstralloc(), biseq(), blength, bSecureDestroy, bsetsize, check, check_then, CRYPT_ENV_MSG, CryptState_nonce_inc, ensure, global_cipher_idx, ltc_ok, CryptState::me, Node_decons(), CryptPeer::nonce, NONCE_LENGTH, and CryptNonce::raw.

Referenced by CryptState_decrypt_node().

Here is the call graph for this function:

void CryptState_destroy ( CryptState state  ) 

Destroys a state cleanly and securely as possible so that it doesn't use memory anymore.

Definition at line 96 of file crypto.c.

References assert_not, CRYPT_MY_KEY, CRYPT_THEIR_KEY, and CryptState_peer_destroy().

Referenced by Hub_exec(), Peer_destroy(), and Proxy_destroy().

Here is the call graph for this function:

Node* CryptState_encrypt_node ( CryptState state,
symmetric_key *  key,
bstring  header,
Node payload 
)

Convenience function that does the job of translating an arbitrary Node into an encrypted one. It converts the payload to a bstring with Node_bstr() and then encrypts. The header is left alone.

Definition at line 559 of file crypto.c.

References assert_not, bSecureDestroy, check, CryptState_encrypt_packet(), Node_bstr(), and on_fail.

Referenced by CryptState_initiator_send_final(), CryptState_initiator_start(), CryptState_receiver_send_final(), Peer_send(), and Proxy_hub_send().

Here is the call graph for this function:

Node* CryptState_encrypt_packet ( CryptState state,
symmetric_key *  key,
bstring  header,
bstring  payload 
)

Used to encrypt raw bstring payload with an AAD (Additional Authenticated Data) header to ensure message integrity. It properly increments the random nonce for each message and returns a Node that wraps the payload in a envelope.

The payload is actually encrypted in place and attached to the returned Node, so you don't bdestroy(payload) but instead just Node_destroy() the return value.

The header is not included in the returned message.

Definition at line 530 of file crypto.c.

References assert_not, bdata, bfromcstralloc(), blength, bsetsize, CRYPT_ENV_MSG, CryptState_nonce_inc, global_cipher_idx, ltc_ok, Node_cons(), CryptPeer::nonce, NONCE_LENGTH, on_fail, CryptNonce::raw, and CryptState::them.

Referenced by CryptState_encrypt_node().

Here is the call graph for this function:

bstring CryptState_export_key ( CryptState state,
crypt_key_side  my_key,
int  type 
)

Exports the raw data of the internal ECC key to a bstring for storage or transmission. my_key indicates whether to export your key or their key, and type is LTC setting of PK_PUBLIC or PK_PRIVATE to indicate the type of key. If you specify PK_PRIVATE that already assumes a PK_PUBLIC export as well (meaning you don't have to call this again to save the public key as well).

Definition at line 192 of file crypto.c.

References assert_mem, assert_not, bdata, bfromcstralloc(), bSecureDestroy, bsetsize, check, CRYPT_MY_KEY, CRYPT_THEIR_KEY, CryptPeer::key, ltc_ok, CryptState::me, on_fail, and CryptState::them.

Referenced by CryptState_fingerprint_key(), CryptState_initiator_start(), CryptState_receiver_start(), Hub_exec(), Member_create(), Proxy_confirm_key(), and Proxy_final_verify().

Here is the call graph for this function:

int CryptState_finalize_session ( CryptState state  )  [inline]

Definition at line 505 of file crypto.c.

References assert_not, bdata, blength, bSecureDestroy, ensure, ltc_ok, CryptState::me, CryptPeer::session, CryptState::shared, CryptPeer::skey, and CryptState::them.

Referenced by CryptState_initiator_send_final(), and CryptState_receiver_done().

bstring CryptState_fingerprint_bstr ( bstring  key  ) 

Returns the same fingerprint as CryptState_fingerprint_key except it works on any bstring of any length. This function is used by CryptState_fingerprint_key to do the actual fingerprinting.

Definition at line 672 of file crypto.c.

References assert_mem, bdata, bdestroy(), bformata(), bfromcstralloc(), blength, global_hash_idx, ltc_ok, and on_fail.

Referenced by CryptState_fingerprint_key(), and Proxy_dump_invalid_state().

Here is the call graph for this function:

bstring CryptState_fingerprint_key ( CryptState state,
crypt_key_side  my_key,
int  type 
)

Returns a fingerprint (sha256 hash of key) for you to show a user. It is pre-formatted to be in hex with dashes between each two hash bytes:

bf27-3806-2dc6-19a0-894d-a3ff-875b-9685-4fba-a2b2-0635-cb94-3494-e1e2-b04b-1f45

As an example. It is kind of slow so don't do billions of these, but not so slow that you need to avoid it.

Definition at line 653 of file crypto.c.

References assert_mem, bdestroy(), check, CRYPT_MY_KEY, CRYPT_THEIR_KEY, CryptState_export_key(), CryptState_fingerprint_bstr(), and on_fail.

Referenced by CryptState_print_key().

Here is the call graph for this function:

Node* CryptState_generate_hate_challenge ( CryptState state,
unsigned int  level,
unsigned long long *  expecting 
)

Constructs a signed hate challenge that the receiver must process. The algorithm is to construct two unsigned long long integers and hash them. The receiver is then only given one of the numbers and has to calculate:

sha256(left:right)

By guessing the right number. This conveniently is the same as a nonce used in the system, so they just have to calculate the sha256 of a nonce that has the right side set to X. They know they're done when they have the same hash.

The hash is signed so that the receiver can validate the challenge actually came from who they claimed.

The level parameter indicates how large of a value as in 2^level maximum for the right side. Larger values mean more work for the receiver.

Definition at line 720 of file crypto.c.

References assert_not, bdata, bfromcstralloc(), blength, blk2bstr(), bsetsize, check, CRYPT_CHALLENGE_MSG, CryptState_create_nonce(), CryptState_hash_nonce(), ensure, global_prng, global_prng_idx, CryptPeer::key, ltc_ok, CryptState::me, Node_cons(), NONCE_LENGTH, CryptNonce::num, CryptNonce::raw, and CryptNonce::right.

Here is the call graph for this function:

bstring CryptState_hash_nonce ( CryptNonce nonce  )  [inline]

Definition at line 703 of file crypto.c.

References assert_mem, assert_not, bdata, bdestroy(), bfromcstralloc(), bsetsize, global_hash_idx, ltc_ok, NONCE_LENGTH, on_fail, and CryptNonce::raw.

Referenced by CryptState_answer_hate_challenge(), CryptState_generate_hate_challenge(), and CryptState_validate_hate_challenge().

Here is the call graph for this function:

int CryptState_import_key ( CryptState state,
crypt_key_side  my_key,
bstring  from 
)

Takes a bstring from crypt_export_key and loads it into the appropriate key for my_key side. You don't need to specify whether the key is public or private as the encoding says this.

Definition at line 220 of file crypto.c.

References assert_not, bdata, blength, CRYPT_MY_KEY, CRYPT_THEIR_KEY, CryptPeer::key, ltc_ok, CryptState::me, on_fail, and CryptState::them.

Referenced by CryptState_create(), and CryptState_create_shared_key().

int CryptState_init (  ) 

Called once for the whole application, this initializes all the various LTC infrastructure needed to get things going.

Definition at line 40 of file crypto.c.

References CIPHER_NAME, CryptState_initialized, global_cipher_idx, global_hash_idx, global_prng, global_prng_idx, HASH_NAME, ltc_mp, ltc_ok, on_fail, and PRNG_NAME.

Referenced by Hub_init(), and Proxy_connect().

int CryptState_initiator_process_response ( CryptState state,
bstring  header,
Node msg 
)

The initiator calls this to process the receiver's final message sent from CryptState_receiver_send_final() and validate it. The caller should also confirm the receiver identity and key after this possibly prompting the user.

Definition at line 441 of file crypto.c.

References assert_not, bisstemeqblk(), blength, bSecureDestroy, check, check_then, CRYPT_RECV_MSG, CryptState_decrypt_node(), CryptState_nonce_set, ensure, CryptState::me, CryptPeer::name, Node_decons(), Node_destroy(), CryptPeer::nonce, NONCE_LENGTH, CryptNonce::raw, CryptPeer::session, CryptState::shared, and CryptState::them.

Referenced by Peer_establish_initiator(), and Proxy_connect().

Here is the call graph for this function:

Node* CryptState_initiator_send_final ( CryptState state,
bstring hbuf 
)

Finally, the initiator sends a small encrypted message with the nonce that the receiver sent in order to prove that they actually received the message and are actually the claimed initiator. The receiver processes this with CryptState_receiver_done().

Just like CryptState_receiver_done() this method clears the shared key and finalizes the two session keys for further encrypted communication.

Definition at line 478 of file crypto.c.

References assert_not, bfromcstr(), blk2bstr(), check, CRYPT_INIT_MSG, CryptState_encrypt_node(), CryptState_finalize_session(), ensure, Node_cons(), Node_destroy(), CryptPeer::nonce, NONCE_LENGTH, CryptNonce::raw, CryptState::shared, and CryptState::them.

Referenced by Peer_establish_initiator(), and Proxy_connect().

Here is the call graph for this function:

Node* CryptState_initiator_start ( CryptState state,
Node recv_start,
bstring hbuf,
CryptState_key_confirm_cb  key_confirm 
)

The first call the initiator to create their first response to the receiver proving their identity. It puts a header in *hbuf as an output parameter, and takes the Node returned from CryptState_receiver_start() as it's input. The Node that gets returned should be sent after the header so the receiver can process it to extract the encrypted payload and wire up the initiator's peer.

The receiver will then call CryptState_receiver_send_final() to send it's reply to the initiator proving the receiver's identity.

Definition at line 397 of file crypto.c.

References assert_not, blk2bstr(), bstrcpy(), check, CRYPT_HEADER, CRYPT_INIT_MSG, CRYPT_MY_KEY, CryptState_create_nonce(), CryptState_create_shared_key(), CryptState_encrypt_node(), CryptState_export_key(), ensure, CryptState::me, CryptPeer::name, Node_bstr(), Node_cons(), Node_destroy(), CryptPeer::nonce, NONCE_LENGTH, CryptNonce::raw, CryptPeer::session, and CryptState::shared.

Referenced by Peer_establish_initiator(), and Proxy_connect().

Here is the call graph for this function:

void CryptState_peer_destroy ( CryptState state,
crypt_key_side  my_key 
)

Used internally to destroy a peer cleanly and safely.

Definition at line 82 of file crypto.c.

References assert_not, bSecureDestroy, CRYPT_MY_KEY, CRYPT_THEIR_KEY, CryptPeer::key, CryptState::me, CryptPeer::name, CryptPeer::nonce, CryptPeer::session, CryptPeer::skey, and CryptState::them.

Referenced by CryptState_destroy(), and CryptState_reset().

void CryptState_print_key ( CryptState state,
crypt_key_side  my_key,
int  type 
)

Prints a key in base64 so you can check it out.

Definition at line 635 of file crypto.c.

References bdata, bSecureDestroy, check, CryptState_fingerprint_key(), and ensure.

Here is the call graph for this function:

int CryptState_rand ( void *  data,
size_t  len 
)

Generates randomness from the internal random number generator (fortuna).

Definition at line 169 of file crypto.c.

References assert_not, and global_prng.

Referenced by Circuit_create(), CryptState_create_nonce(), and CryptState_rand_sess().

void CryptState_rand_sess ( CryptState state  )  [inline]

Definition at line 106 of file crypto.c.

References assert_mem, assert_not, bfromcstralloc(), bsetsize, CryptState_rand(), tagbstring::data, KEY_LENGTH, CryptState::me, and CryptPeer::session.

Referenced by CryptState_create(), and CryptState_reset().

Here is the call graph for this function:

int CryptState_receiver_done ( CryptState state,
bstring  header,
Node msg 
) [inline]

After the initiator validates the receiver's final message, they return one more message with crypt_initiator_send_final to confirm that they actually are the recipients of the receiver's nonce and key. The receiver processes this message with this function.

Once all the nonces and keys are confirmed to match, the shared key is cleared out and the session keys for both sides are locked down for the remaining messages. The shared key is cleared to reduce the chance that it can be read out of memory.

Definition at line 369 of file crypto.c.

References assert_not, bisstemeqblk(), check, check_then, CRYPT_INIT_MSG, CryptState_decrypt_node(), CryptState_finalize_session(), ensure, CryptState::me, Node_decons(), Node_destroy(), CryptPeer::nonce, NONCE_LENGTH, CryptNonce::raw, and CryptState::shared.

Referenced by Peer_establish_receiver().

Here is the call graph for this function:

int CryptState_receiver_process_response ( CryptState state,
bstring  hbuf,
Node payload,
CryptState_key_confirm_cb  key_confirm 
)

Takes the response from CryptState_initiator_start() and processes it to extract the initiator's information and verify it. After this processing you would want to validate the initiator's name, key, etc. to confirm they are allowed to even continue.

Once this works, you then call CryptState_receiver_send_final() to return the message that initiator needs to confirm the receiver's identity.

hbuf is the full header you received as-is.

Definition at line 300 of file crypto.c.

References assert_not, bdestroy(), check, CRYPT_INIT_MSG, CryptState_create_shared_key(), CryptState_decrypt_node(), CryptState_nonce_set, CryptPeer::name, Node_decons(), Node_destroy(), Node_parse(), CryptPeer::nonce, on_fail, CryptPeer::session, CryptState::shared, and CryptState::them.

Referenced by Peer_establish_receiver().

Here is the call graph for this function:

Node* CryptState_receiver_send_final ( CryptState state,
bstring hbuf 
)

Generates the final message sent back to the initiator to prove the receiver's identity. The initiator uses CryptState_initiator_process_response() to extract the receiver's information and verify it's validity.

hbuf is an out parameter that contains the header to send to the initiator exactly as-is.

Definition at line 336 of file crypto.c.

References assert_not, bfromcstr(), blk2bstr(), bstrcpy(), check, CRYPT_RECV_MSG, CryptState_create_nonce(), CryptState_encrypt_node(), ensure, CryptState::me, CryptPeer::name, Node_cons(), Node_destroy(), CryptPeer::nonce, NONCE_LENGTH, CryptNonce::raw, CryptPeer::session, CryptState::shared, and CryptState::them.

Referenced by Peer_establish_receiver().

Here is the call graph for this function:

Node* CryptState_receiver_start ( CryptState state  ) 

The first function call in the establish sequence, this returns a message to be sent to the initiator so they can call CryptState_initiator_start() to begin their processing.

Definition at line 281 of file crypto.c.

References assert_not, blk2bstr(), check, CRYPT_HEADER, CRYPT_MY_KEY, CryptState_create_nonce(), CryptState_export_key(), CryptState::me, Node_cons(), CryptPeer::nonce, NONCE_LENGTH, on_fail, and CryptNonce::raw.

Referenced by Peer_establish_receiver().

Here is the call graph for this function:

void CryptState_reset ( CryptState state  ) 

A faster way to reuse a state for another communication. Rather than continually calling CryptState_init to recreate your side, this function just clears the CryptState to where it is exactly like you just called CryptState_init.

Definition at line 153 of file crypto.c.

References assert_not, CRYPT_THEIR_KEY, CryptState_peer_destroy(), CryptState_rand_sess(), CryptState::me, CryptPeer::nonce, CryptState::shared, and CryptPeer::skey.

Here is the call graph for this function:

int CryptState_validate_hate_challenge ( CryptState state,
Node challenge,
Node answer,
unsigned long long  expecting 
)

Definition at line 840 of file crypto.c.

References assert_not, bdata, bdestroy(), biseq(), blength, check, CRYPT_ANSWER_MSG, CRYPT_CHALLENGE_MSG, CryptState_hash_nonce(), CryptState_nonce_set, CryptPeer::key, CryptNonce::left, ltc_ok, Node_decons(), CryptNonce::num, on_fail, CryptNonce::right, and CryptState::them.

Here is the call graph for this function:


Variable Documentation

int CryptState_initialized = 0 [static]

Definition at line 38 of file crypto.c.

Referenced by CryptState_init().

int global_cipher_idx [static]

Definition at line 36 of file crypto.c.

Referenced by CryptState_decrypt_packet(), CryptState_encrypt_packet(), and CryptState_init().

int global_hash_idx [static]

Definition at line 34 of file crypto.c.

Referenced by CryptState_answer_hate_challenge(), CryptState_fingerprint_bstr(), CryptState_hash_nonce(), and CryptState_init().

prng_state global_prng [static]

Definition at line 33 of file crypto.c.

Referenced by CryptState_answer_hate_challenge(), CryptState_create_key(),