diff --git a/include/llarp/bencode.h b/include/llarp/bencode.h index 28d65b587..8e7b5d339 100644 --- a/include/llarp/bencode.h +++ b/include/llarp/bencode.h @@ -124,7 +124,7 @@ bdecode_read_string(llarp_buffer_t* buffer, llarp_buffer_t* result) buffer->cur++; - len = llarp_buffer_size_left(buffer); + len = llarp_buffer_size_left(*buffer); if(len < slen) return false; @@ -157,7 +157,7 @@ bdecode_read_dict(llarp_buffer_t* buff, struct dict_reader* r) if(*r->buffer->cur != 'd') // ensure is a dictionary return false; r->buffer->cur++; - while(llarp_buffer_size_left(r->buffer) && *r->buffer->cur != 'e') + while(llarp_buffer_size_left(*r->buffer) && *r->buffer->cur != 'e') { if(bdecode_read_string(r->buffer, &strbuf)) { @@ -180,8 +180,8 @@ struct list_reader /// information to on_item void* user; /** - * called when we got an element, return true to continue iteration - * called with null item on iteration completion + * called with true when we got an element, return true to continue iteration + * called with false on iteration completion */ bool (*on_item)(struct list_reader*, bool); }; @@ -194,7 +194,7 @@ bdecode_read_list(llarp_buffer_t* buff, struct list_reader* r) return false; r->buffer->cur++; - while(llarp_buffer_size_left(r->buffer) && *r->buffer->cur != 'e') + while(llarp_buffer_size_left(*r->buffer) && *r->buffer->cur != 'e') { if(!r->on_item(r, true)) // check for early abort return false; diff --git a/include/llarp/buffer.h b/include/llarp/buffer.h index eae5aa4ac..9f350b127 100644 --- a/include/llarp/buffer.h +++ b/include/llarp/buffer.h @@ -10,7 +10,7 @@ /** * buffer.h * - * buffer used for bencoding + * generic memory buffer */ #ifdef __cplusplus @@ -19,6 +19,29 @@ extern "C" { typedef uint8_t byte_t; +/** + llarp_buffer_t represents a region of memory that is ONLY + accessable and valid in the current scope. + + rules: + + ALWAYS copy the contents of the buffer + if that data is to be used outside the current scope. + + ALWAYS pass a llarp_buffer_t * if you plan on modifying + the data associated with the buffer + + ALWAYS pass a llarp_buffer_t * if you plan on advancing + the stream position + + ALWAYS pass a llarp_buffer_t if you are doing a read + only operation that does not modify anything + + NEVER dallocate the pointers in the buffer + + NEVER use llarp_buffer_t ** (double pointer) + + */ typedef struct llarp_buffer_t { /// starting memory address @@ -31,7 +54,7 @@ typedef struct llarp_buffer_t /// how much room is left in buffer size_t -llarp_buffer_size_left(llarp_buffer_t *buff); +llarp_buffer_size_left(llarp_buffer_t buff); /// write a chunk of data size "sz" bool diff --git a/include/llarp/crypto.h b/include/llarp/crypto.h index 15cfc6be8..afc0eb2f4 100644 --- a/include/llarp/crypto.h +++ b/include/llarp/crypto.h @@ -43,53 +43,72 @@ byte_t * llarp_seckey_topublic(byte_t *secret); /// label functors + +/// PKE(result, publickey, nonce, secretkey) typedef bool (*llarp_dh_func)(llarp_sharedkey_t *, llarp_pubkey_t, llarp_tunnel_nonce_t, llarp_seckey_t); +/// TKE(result publickey, secretkey, nonce) typedef bool (*llarp_transport_dh_func)(byte_t *, byte_t *, byte_t *, byte_t *); +/// SD/SE(buffer, key, nonce) typedef bool (*llarp_sym_cipher_func)(llarp_buffer_t, llarp_sharedkey_t, llarp_nonce_t); +/// H(result, body) typedef bool (*llarp_hash_func)(byte_t *, llarp_buffer_t); +/// SH(result, body) typedef bool (*llarp_shorthash_func)(byte_t *, llarp_buffer_t); +/// MDS(result, body, shared_secret) typedef bool (*llarp_hmac_func)(byte_t *, llarp_buffer_t, const byte_t *); +/// S(sig, secretkey, body) typedef bool (*llarp_sign_func)(byte_t *, const byte_t *, llarp_buffer_t); +/// V(sig, body, secretkey) typedef bool (*llarp_verify_func)(const byte_t *, llarp_buffer_t, const byte_t *); -typedef bool (*llarp_frame_crypto_func)(llarp_buffer_t *, const byte_t *); - /// library crypto configuration struct llarp_crypto { + /// xchacha symettric cipher llarp_sym_cipher_func xchacha20; + /// path dh creator's side llarp_dh_func dh_client; + /// path dh relay side llarp_dh_func dh_server; + /// transport dh client side llarp_transport_dh_func transport_dh_client; + /// transport dh server side llarp_transport_dh_func transport_dh_server; + /// blake2b 512 bit llarp_hash_func hash; + /// blake2b 256 bit llarp_shorthash_func shorthash; + /// blake2s 256 bit hmac llarp_hmac_func hmac; + /// ed25519 sign llarp_sign_func sign; + /// ed25519 verify llarp_verify_func verify; - llarp_frame_crypto_func encrypt_frame; - llarp_frame_crypto_func decrypt_frame; + /// randomize buffer void (*randomize)(llarp_buffer_t); + /// randomizer memory void (*randbytes)(void *, size_t); + /// generate signing keypair void (*identity_keygen)(byte_t *); + /// generate encryption keypair void (*encryption_keygen)(byte_t *); }; -/// allocate crypto +/// set crypto function pointers to use libsodium void llarp_crypto_libsodium_init(struct llarp_crypto *c); -/// initialize crypto +/// check for initialize crypto bool llarp_crypto_initialized(struct llarp_crypto *c); diff --git a/include/llarp/crypto_async.h b/include/llarp/crypto_async.h index 2a1e2b2e7..8134436e2 100644 --- a/include/llarp/crypto_async.h +++ b/include/llarp/crypto_async.h @@ -15,10 +15,15 @@ extern "C" { #endif +/// context for doing asynchronous crpytography for iwp +/// with a worker threadpool /// defined in crypto_async.cpp struct llarp_async_iwp; /// allocator +/// use crypto as cryptograph implementation +/// use logic as the callback handler thread +/// use worker as threadpool that does the heavy lifting struct llarp_async_iwp * llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic, struct llarp_threadpool *worker); @@ -41,11 +46,11 @@ struct iwp_async_keygen void *user; /// destination key buffer uint8_t *keybuf; - /// iteration functor + /// result handler callback iwp_keygen_hook hook; }; -/// generate a key by iterating on "iwp" using "keygen" request +/// generate an encryption keypair asynchronously void iwp_call_async_keygen(struct llarp_async_iwp *iwp, struct iwp_async_keygen *keygen); @@ -72,11 +77,12 @@ struct iwp_async_intro iwp_intro_hook hook; }; -/// introduce internal wire protocol "iwp" using "intro" request +/// asynchronously generate an intro packet void iwp_call_async_gen_intro(struct llarp_async_iwp *iwp, struct iwp_async_intro *intro); +/// asynchronously verify an intro packet void iwp_call_async_verify_intro(struct llarp_async_iwp *iwp, struct iwp_async_intro *info); @@ -105,12 +111,12 @@ struct iwp_async_introack iwp_introack_hook hook; }; -/// generate introduction acknowledgement "iwp" using "introack" request +/// generate introduction acknowledgement packet asynchronously void iwp_call_async_gen_introack(struct llarp_async_iwp *iwp, struct iwp_async_introack *introack); -/// verify introduction acknowledgement "iwp" using "introack" request +/// verify introduction acknowledgement packet asynchronously void iwp_call_async_verify_introack(struct llarp_async_iwp *iwp, struct iwp_async_introack *introack); @@ -127,20 +133,26 @@ struct iwp_async_session_start void *user; uint8_t *buf; size_t sz; + /// nonce parameter uint8_t *nonce; + /// token parameter uint8_t *token; + /// memory to write session key to uint8_t *sessionkey; + /// local secrkey key uint8_t *secretkey; + /// remote public encryption key uint8_t *remote_pubkey; + /// result callback handler iwp_session_start_hook hook; }; -/// generate session start "iwp" using "start" request +/// generate session start packet asynchronously void iwp_call_async_gen_session_start(struct llarp_async_iwp *iwp, struct iwp_async_session_start *start); -/// verify session start "iwp" using "start" request +/// verify session start packet asynchronously void iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp, struct iwp_async_session_start *start); @@ -152,21 +164,26 @@ typedef void (*iwp_async_frame_hook)(struct iwp_async_frame *); struct iwp_async_frame { + /// true if decryption succeded bool success; struct llarp_async_iwp *iwp; void *user; + /// current session key uint8_t *sessionkey; + /// size of the frame size_t sz; + /// result handler iwp_async_frame_hook hook; + /// memory holding the entire frame uint8_t buf[1500]; }; -/// decrypt iwp frame "iwp" using "frame" request +/// decrypt iwp frame asynchronously void iwp_call_async_frame_decrypt(struct llarp_async_iwp *iwp, struct iwp_async_frame *frame); -/// encrypt iwp frame "iwp" using "frame" request +/// encrypt iwp frame asynchronously void iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp, struct iwp_async_frame *frame); diff --git a/llarp/buffer.cpp b/llarp/buffer.cpp index 474b965c6..bbb5e5f4a 100644 --- a/llarp/buffer.cpp +++ b/llarp/buffer.cpp @@ -5,20 +5,20 @@ extern "C" { size_t -llarp_buffer_size_left(llarp_buffer_t* buff) +llarp_buffer_size_left(llarp_buffer_t buff) { - size_t diff = buff->cur - buff->base; - if(diff > buff->sz) + size_t diff = buff.cur - buff.base; + if(diff > buff.sz) return 0; else - return buff->sz - diff; + return buff.sz - diff; } bool llarp_buffer_writef(llarp_buffer_t* buff, const char* fmt, ...) { int written; - ssize_t sz = llarp_buffer_size_left(buff); + ssize_t sz = llarp_buffer_size_left(*buff); va_list args; va_start(args, fmt); written = vsnprintf((char*)buff->cur, sz, fmt, args); @@ -34,7 +34,7 @@ llarp_buffer_writef(llarp_buffer_t* buff, const char* fmt, ...) bool llarp_buffer_write(llarp_buffer_t* buff, const void* data, size_t sz) { - size_t left = llarp_buffer_size_left(buff); + size_t left = llarp_buffer_size_left(*buff); if(left >= sz) { memcpy(buff->cur, data, sz); @@ -60,7 +60,7 @@ llarp_buffer_read_until(llarp_buffer_t* buff, char delim, byte_t* result, read++; } - if(llarp_buffer_size_left(buff)) + if(llarp_buffer_size_left(*buff)) return read; else return 0;