int main(void) { sodium_init(); //create a user_store user_store *store = user_store_create(); //check the content buffer_t *list = user_store_list(store); if (list->content_length != 0) { fprintf(stderr, "ERROR: List of users is not empty.\n"); user_store_destroy(store); buffer_destroy_from_heap(list); return EXIT_FAILURE; } buffer_destroy_from_heap(list); int status; //create three users with prekeys and identity keys //first alice //alice identity key buffer_t *alice_private_identity = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *alice_public_identity = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); status = generate_and_print_keypair( alice_public_identity->content, alice_private_identity->content, "Alice", "identity"); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Alice's identity keypair.\n"); buffer_clear(alice_private_identity); return status; } //alice prekeys buffer_t *alice_private_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES, PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES); buffer_t *alice_public_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES, PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES); status = generate_prekeys(alice_private_prekeys, alice_public_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Alice's prekeys.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); return status; } //make illegal access to the user store printf("User store length: %zi\n", store->length); //The program should crash here! user_store_destroy(store); return EXIT_SUCCESS; }
int main(void) { sodium_init(); int status; //create Alice's keypair unsigned char alice_public_key[crypto_box_PUBLICKEYBYTES]; unsigned char alice_private_key[crypto_box_SECRETKEYBYTES]; status = generate_and_print_keypair( alice_public_key, alice_private_key, "Alice", ""); if (status != 0) { sodium_memzero(alice_private_key, crypto_box_SECRETKEYBYTES); return status; } //create Bob's keypair unsigned char bob_public_key[crypto_box_PUBLICKEYBYTES]; unsigned char bob_private_key[crypto_box_SECRETKEYBYTES]; status = generate_and_print_keypair( bob_public_key, bob_private_key, "Bob", ""); if (status != 0) { sodium_memzero(alice_private_key, crypto_box_SECRETKEYBYTES); sodium_memzero(bob_private_key, crypto_box_SECRETKEYBYTES); return status; } //Diffie Hellman on Alice's side unsigned char alice_shared_secret[crypto_generichash_BYTES]; status = diffie_hellman( alice_shared_secret, alice_private_key, alice_public_key, bob_public_key, true); sodium_memzero(alice_private_key, crypto_box_SECRETKEYBYTES); if (status != 0) { fprintf(stderr, "ERROR: Diffie Hellman with Alice's private key failed. (%i)\n", status); sodium_memzero(bob_private_key, crypto_box_SECRETKEYBYTES); sodium_memzero(alice_shared_secret, crypto_generichash_BYTES); return status; } //print Alice's shared secret printf("Alice's shared secret ECDH(A_priv, B_pub) (%i Bytes):\n", crypto_generichash_BYTES); print_hex(alice_shared_secret, crypto_generichash_BYTES, 30); putchar('\n'); //Diffie Hellman on Bob's side unsigned char bob_shared_secret[crypto_generichash_BYTES]; status = diffie_hellman( bob_shared_secret, bob_private_key, bob_public_key, alice_public_key, false); sodium_memzero(bob_private_key, crypto_box_SECRETKEYBYTES); if (status != 0) { fprintf(stderr, "ERROR: Diffie Hellman with Bob's private key failed. (%i)\n", status); sodium_memzero(alice_shared_secret, crypto_generichash_BYTES); sodium_memzero(bob_shared_secret, crypto_generichash_BYTES); return status; } //print Bob's shared secret printf("Bob's shared secret ECDH(B_priv, A_pub) (%i Bytes):\n", crypto_generichash_BYTES); print_hex(bob_shared_secret, crypto_generichash_BYTES, 30); putchar('\n'); //compare both shared secrets status = sodium_memcmp(alice_shared_secret, bob_shared_secret, crypto_generichash_BYTES); sodium_memzero(alice_shared_secret, crypto_generichash_BYTES); sodium_memzero(bob_shared_secret, crypto_generichash_BYTES); if (status != 0) { fprintf(stderr, "ERROR: Diffie Hellman didn't produce the same shared secret. (%i)\n", status); return status; } printf("Both shared secrets match!\n"); return EXIT_SUCCESS; }
int main(void) { sodium_init(); int status; //create Alice's identity keypair buffer_t *alice_public_identity = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *alice_private_identity = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); status = generate_and_print_keypair( alice_public_identity, alice_private_identity, buffer_create_from_string("Alice"), buffer_create_from_string("identity")); if (status != 0) { buffer_clear(alice_private_identity); return status; } //create Alice's ephemeral keypair buffer_t *alice_public_ephemeral = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *alice_private_ephemeral = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); status = generate_and_print_keypair( alice_public_ephemeral, alice_private_ephemeral, buffer_create_from_string("Alice"), buffer_create_from_string("ephemeral")); if (status != 0) { buffer_clear(alice_private_identity); buffer_clear(alice_private_ephemeral); return status; } //create Bob's identity keypair buffer_t *bob_public_identity = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *bob_private_identity = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); status = generate_and_print_keypair( bob_public_identity, bob_private_identity, buffer_create_from_string("Bob"), buffer_create_from_string("identity")); if (status != 0) { buffer_clear(alice_private_identity); buffer_clear(alice_private_ephemeral); buffer_clear(bob_private_identity); return status; } //create Bob's ephemeral keypair buffer_t *bob_public_ephemeral = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *bob_private_ephemeral = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); status = generate_and_print_keypair( bob_public_ephemeral, bob_private_ephemeral, buffer_create_from_string("Bob"), buffer_create_from_string("ephemeral")); if (status != 0) { buffer_clear(alice_private_identity); buffer_clear(alice_private_ephemeral); buffer_clear(bob_private_identity); buffer_clear(bob_private_ephemeral); return status; } //derive Alice's initial root and chain key buffer_t *alice_root_key = buffer_create(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *alice_send_chain_key = buffer_create(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *alice_receive_chain_key = buffer_create(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *alice_send_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); buffer_t *alice_receive_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); buffer_t *alice_next_send_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); buffer_t *alice_next_receive_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); status = derive_initial_root_chain_and_header_keys( alice_root_key, alice_send_chain_key, alice_receive_chain_key, alice_send_header_key, alice_receive_header_key, alice_next_send_header_key, alice_next_receive_header_key, alice_private_identity, alice_public_identity, bob_public_identity, alice_private_ephemeral, alice_public_ephemeral, bob_public_ephemeral, true); buffer_clear(alice_private_identity); buffer_clear(alice_private_ephemeral); if (status != 0) { fprintf(stderr, "ERROR: Failed to derive Alice's initial root and chain key. (%i)\n", status); buffer_clear(alice_root_key); buffer_clear(alice_send_chain_key); buffer_clear(alice_receive_chain_key); buffer_clear(alice_send_header_key); buffer_clear(alice_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_private_identity); buffer_clear(bob_private_ephemeral); return status; } //print Alice's initial root and chain key printf("Alice's initial root key (%zi Bytes):\n", alice_root_key->content_length); print_hex(alice_root_key); putchar('\n'); printf("Alice's initial send chain key (%zi Bytes):\n", alice_send_chain_key->content_length); print_hex(alice_send_chain_key); putchar('\n'); printf("Alice's initial receive chain key (%zi Bytes):\n", alice_receive_chain_key->content_length); print_hex(alice_receive_chain_key); putchar('\n'); printf("Alice's initial send header key (%zi Bytes):\n", alice_send_header_key->content_length); print_hex(alice_send_header_key); putchar('\n'); printf("Alice's initial receive header key (%zi Bytes):\n", alice_receive_header_key->content_length); print_hex(alice_receive_header_key); printf("Alice's initial next send header key (%zi Bytes):\n", alice_next_send_header_key->content_length); print_hex(alice_next_send_header_key); putchar('\n'); printf("Alice's initial next receive header key (%zi Bytes):\n", alice_next_receive_header_key->content_length); print_hex(alice_next_receive_header_key); putchar('\n'); //derive Bob's initial root and chain key buffer_t *bob_root_key = buffer_create(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *bob_send_chain_key = buffer_create(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *bob_receive_chain_key = buffer_create(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *bob_send_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); buffer_t *bob_receive_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); buffer_t *bob_next_send_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); buffer_t *bob_next_receive_header_key = buffer_create(crypto_aead_chacha20poly1305_KEYBYTES, crypto_aead_chacha20poly1305_KEYBYTES); status = derive_initial_root_chain_and_header_keys( bob_root_key, bob_send_chain_key, bob_receive_chain_key, bob_send_header_key, bob_receive_header_key, bob_next_send_header_key, bob_next_receive_header_key, bob_private_identity, bob_public_identity, alice_public_identity, bob_private_ephemeral, bob_public_ephemeral, alice_public_ephemeral, false); buffer_clear(bob_private_identity); buffer_clear(bob_private_ephemeral); if (status != 0) { fprintf(stderr, "ERROR: Failed to derive Bob's initial root and chain key. (%i)", status); buffer_clear(alice_root_key); buffer_clear(alice_send_chain_key); buffer_clear(alice_receive_chain_key); buffer_clear(alice_send_header_key); buffer_clear(alice_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_root_key); buffer_clear(bob_send_chain_key); buffer_clear(bob_receive_chain_key); buffer_clear(bob_send_header_key); buffer_clear(bob_receive_header_key); buffer_clear(bob_next_send_header_key); buffer_clear(bob_next_receive_header_key); return status; } //print Bob's initial root and chain key printf("Bob's initial root key (%zi Bytes):\n", bob_root_key->content_length); print_hex(bob_root_key); putchar('\n'); printf("Bob's initial send chain key (%zi Bytes):\n", bob_send_chain_key->content_length); print_hex(bob_send_chain_key); putchar('\n'); printf("Bob's initial receive chain key (%zi Bytes):\n", bob_receive_chain_key->content_length); print_hex(bob_receive_chain_key); putchar('\n'); printf("Bob's initial send header key (%zi Bytes):\n", bob_send_header_key->content_length); print_hex(bob_send_header_key); putchar('\n'); printf("Bob's initial receive header key (%zi Bytes):\n", bob_receive_header_key->content_length); print_hex(bob_receive_header_key); printf("Bob's initial next send header key (%zi Bytes):\n", bob_next_send_header_key->content_length); print_hex(bob_next_send_header_key); putchar('\n'); printf("Bob's initial next receive header key (%zi Bytes):\n", bob_next_receive_header_key->content_length); print_hex(bob_next_receive_header_key); putchar('\n'); //compare Alice's and Bob's initial root key if (buffer_compare(alice_root_key, bob_root_key) != 0) { fprintf(stderr, "ERROR: Alice's and Bob's initial root keys don't match.\n"); buffer_clear(alice_root_key); buffer_clear(alice_send_chain_key); buffer_clear(alice_receive_chain_key); buffer_clear(alice_send_header_key); buffer_clear(alice_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_root_key); buffer_clear(bob_send_chain_key); buffer_clear(bob_receive_chain_key); buffer_clear(bob_send_header_key); buffer_clear(bob_receive_header_key); buffer_clear(bob_next_send_header_key); buffer_clear(bob_next_receive_header_key); return -10; } printf("Alice's and Bob's initial root keys match.\n"); buffer_clear(alice_root_key); buffer_clear(bob_root_key); //compare Alice's and Bob's initial chain keys if (buffer_compare(alice_send_chain_key, bob_receive_chain_key) != 0) { fprintf(stderr, "ERROR: Alice's and Bob's initial chain keys don't match.\n"); buffer_clear(alice_send_chain_key); buffer_clear(alice_receive_chain_key); buffer_clear(alice_send_header_key); buffer_clear(alice_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_send_chain_key); buffer_clear(bob_receive_chain_key); buffer_clear(bob_send_header_key); buffer_clear(bob_receive_header_key); buffer_clear(bob_next_send_header_key); buffer_clear(bob_next_receive_header_key); return -10; } printf("Alice's and Bob's initial chain keys match.\n"); buffer_clear(alice_send_chain_key); buffer_clear(bob_receive_chain_key); if (buffer_compare(alice_receive_chain_key, bob_send_chain_key) != 0) { fprintf(stderr, "ERROR: Alice's and Bob's initial chain keys don't match.\n"); buffer_clear(alice_receive_chain_key); buffer_clear(alice_send_header_key); buffer_clear(alice_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_send_chain_key); buffer_clear(bob_send_header_key); buffer_clear(bob_receive_header_key); buffer_clear(bob_next_send_header_key); buffer_clear(bob_next_receive_header_key); return -10; } printf("Alice's and Bob's initial chain keys match.\n"); //compare Alice's and Bob's initial header keys 1/2 if (buffer_compare(alice_send_header_key, bob_receive_header_key) != 0) { fprintf(stderr, "ERROR: Alice's initial send and Bob's initial receive header keys don't match.\n"); buffer_clear(alice_send_header_key); buffer_clear(alice_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_send_header_key); buffer_clear(bob_receive_header_key); buffer_clear(bob_next_send_header_key); buffer_clear(bob_next_receive_header_key); return -10; } printf("Alice's initial send and Bob's initial receive header keys match.\n"); buffer_clear(alice_send_header_key); buffer_clear(bob_receive_header_key); //compare Alice's and Bob's initial header keys 2/2 if (buffer_compare(alice_receive_header_key, bob_send_header_key) != 0) { fprintf(stderr, "ERROR: Alice's initial receive and Bob's initial send header keys don't match.\n"); buffer_clear(alice_receive_header_key); buffer_clear(alice_next_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(bob_send_header_key); buffer_clear(bob_next_send_header_key); buffer_clear(bob_next_receive_header_key); return -10; } printf("Alice's initial receive and Bob's initial send header keys match.\n"); buffer_clear(alice_receive_header_key); buffer_clear(bob_send_header_key); //compare Alice's and Bob's initial next header keys 1/2 if (buffer_compare(alice_next_send_header_key, bob_next_receive_header_key) != 0) { fprintf(stderr, "ERROR: Alice's initial next send and Bob's initial next receive header keys don't match.\n"); buffer_clear(alice_next_receive_header_key); buffer_clear(alice_next_send_header_key); buffer_clear(bob_next_send_header_key); buffer_clear(bob_next_receive_header_key); return -10; } printf("Alice's initial next send and Bob's initial next receive header keys match.\n"); buffer_clear(alice_next_send_header_key); buffer_clear(bob_next_receive_header_key); //compare Alice's and Bob's initial next header keys 2/2 if (buffer_compare(alice_next_receive_header_key, bob_next_send_header_key) != 0) { fprintf(stderr, "ERROR: Alice's initial next receive and Bob's initial next send header keys don't match.\n"); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_next_send_header_key); return -10; } printf("Alice's initial next receive and Bob's initial next send header keys match.\n"); buffer_clear(alice_next_receive_header_key); buffer_clear(bob_next_send_header_key); return EXIT_SUCCESS; }
int main(void) { if (sodium_init() == -1) { return -1; } return_status status = return_status_init(); //create buffers buffer_t *alice_public_key = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *alice_private_key = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *alice_shared_secret = buffer_create_on_heap(crypto_generichash_BYTES, crypto_generichash_BYTES); buffer_t *bob_public_key = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *bob_private_key = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *bob_shared_secret = buffer_create_on_heap(crypto_generichash_BYTES, crypto_generichash_BYTES); int status_int = 0; //create Alice's keypair buffer_create_from_string(alice_string, "Alice"); buffer_create_from_string(empty_string, ""); status = generate_and_print_keypair( alice_public_key, alice_private_key, alice_string, empty_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Alice's keypair."); //create Bob's keypair buffer_create_from_string(bob_string, "Bob"); status = generate_and_print_keypair( bob_public_key, bob_private_key, bob_string, empty_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Bob's keypair."); //Diffie Hellman on Alice's side status = diffie_hellman( alice_shared_secret, alice_private_key, alice_public_key, bob_public_key, true); buffer_clear(alice_private_key); throw_on_error(KEYGENERATION_FAILED, "Diffie Hellman with Alice's private key failed."); //print Alice's shared secret printf("Alice's shared secret ECDH(A_priv, B_pub) (%zu Bytes):\n", alice_shared_secret->content_length); print_hex(alice_shared_secret); putchar('\n'); //Diffie Hellman on Bob's side status = diffie_hellman( bob_shared_secret, bob_private_key, bob_public_key, alice_public_key, false); buffer_clear(bob_private_key); throw_on_error(KEYGENERATION_FAILED, "Diffie Hellman with Bob's private key failed."); //print Bob's shared secret printf("Bob's shared secret ECDH(B_priv, A_pub) (%zu Bytes):\n", bob_shared_secret->content_length); print_hex(bob_shared_secret); putchar('\n'); //compare both shared secrets status_int = buffer_compare(alice_shared_secret, bob_shared_secret); buffer_clear(alice_shared_secret); buffer_clear(bob_shared_secret); if (status_int != 0) { throw(INCORRECT_DATA, "Diffie Hellman didn't produce the same shared secret."); } printf("Both shared secrets match!\n"); cleanup: buffer_destroy_from_heap_and_null_if_valid(alice_public_key); buffer_destroy_from_heap_and_null_if_valid(alice_private_key); buffer_destroy_from_heap_and_null_if_valid(alice_shared_secret); buffer_destroy_from_heap_and_null_if_valid(bob_public_key); buffer_destroy_from_heap_and_null_if_valid(bob_private_key); buffer_destroy_from_heap_and_null_if_valid(bob_shared_secret); on_error { print_errors(&status); } return_status_destroy_errors(&status); return status.status; }
int main(void) { sodium_init(); //create a user_store user_store *store = user_store_create(); //check the content buffer_t *list = user_store_list(store); if (list->content_length != 0) { fprintf(stderr, "ERROR: List of users is not empty.\n"); user_store_destroy(store); buffer_destroy_from_heap(list); return EXIT_FAILURE; } buffer_destroy_from_heap(list); int status; //create three users with prekeys and identity keys //first alice //alice identity key buffer_t *alice_private_identity = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *alice_public_identity = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); status = generate_and_print_keypair( alice_public_identity, alice_private_identity, buffer_create_from_string("Alice"), buffer_create_from_string("identity")); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Alice's identity keypair.\n"); buffer_clear(alice_private_identity); return status; } //alice prekeys buffer_t *alice_private_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES, PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES); buffer_t *alice_public_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES, PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES); status = generate_prekeys(alice_private_prekeys, alice_public_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Alice's prekeys.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); return status; } //then bob //bob's identity key buffer_t *bob_private_identity = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *bob_public_identity = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); status = generate_and_print_keypair( bob_public_identity, bob_private_identity, buffer_create_from_string("Bob"), buffer_create_from_string("identity")); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Bob's identity keypair.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); return status; } //bob's prekeys buffer_t *bob_private_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES, PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES); buffer_t *bob_public_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES, PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES); status = generate_prekeys(bob_private_prekeys, bob_public_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Bob's prekeys.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); return status; } //then charlie //charlie's identity key buffer_t *charlie_private_identity = buffer_create(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *charlie_public_identity = buffer_create(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); status = generate_and_print_keypair( charlie_public_identity, charlie_private_identity, buffer_create_from_string("Charlie"), buffer_create_from_string("identity")); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Charlie's identity keypair.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); return status; } //charlie's prekeys buffer_t *charlie_private_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES, PREKEY_AMOUNT * crypto_box_SECRETKEYBYTES); buffer_t *charlie_public_prekeys = buffer_create(PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES, PREKEY_AMOUNT * crypto_box_PUBLICKEYBYTES); status = generate_prekeys(charlie_private_prekeys, charlie_public_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to generate Charlie's prekeys.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); return status; } //add alice to the user store status = user_store_add( store, alice_public_identity, alice_private_identity, alice_public_prekeys, alice_private_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to add Alice to the user store.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return status; } printf("Successfully added Alice to the user store.\n"); //check length of the user store sodium_mprotect_readonly(store); if (store->length != 1) { fprintf(stderr, "ERROR: User store has incorrect length.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } sodium_mprotect_noaccess(store); printf("Length of the user store matches."); //list user store list = user_store_list(store); if (buffer_compare(list, alice_public_identity) != 0) { fprintf(stderr, "ERROR: Failed to list users.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); buffer_destroy_from_heap(list); user_store_destroy(store); return EXIT_FAILURE; } buffer_destroy_from_heap(list); printf("Successfully listed users.\n"); //add bob to the user store status = user_store_add( store, bob_public_identity, bob_private_identity, bob_public_prekeys, bob_private_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to add Bob to the user store.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return status; } printf("Successfully added Bob to the user store.\n"); //check length of the user store sodium_mprotect_readonly(store); if (store->length != 2) { fprintf(stderr, "ERROR: User store has incorrect length.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } sodium_mprotect_noaccess(store); printf("Length of the user store matches."); //list user store list = user_store_list(store); if ((buffer_compare_partial(list, 0, alice_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0) || (buffer_compare_partial(list, crypto_box_PUBLICKEYBYTES, bob_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0)) { fprintf(stderr, "ERROR: Failed to list users.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); buffer_destroy_from_heap(list); user_store_destroy(store); return EXIT_FAILURE; } buffer_destroy_from_heap(list); printf("Successfully listed users.\n"); //add charlie to the user store status = user_store_add( store, charlie_public_identity, charlie_private_identity, charlie_public_prekeys, charlie_private_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to add Charlie to the user store.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return status; } printf("Successfully added Charlie to the user store.\n"); //check length of the user store sodium_mprotect_readonly(store); if (store->length != 3) { fprintf(stderr, "ERROR: User store has incorrect length.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } sodium_mprotect_noaccess(store); printf("Length of the user store matches."); //list user store list = user_store_list(store); if ((buffer_compare_partial(list, 0, alice_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0) || (buffer_compare_partial(list, crypto_box_PUBLICKEYBYTES, bob_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0) || (buffer_compare_partial(list, 2 * crypto_box_PUBLICKEYBYTES, charlie_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0)) { fprintf(stderr, "ERROR: Failed to list users.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); buffer_destroy_from_heap(list); user_store_destroy(store); return EXIT_FAILURE; } buffer_destroy_from_heap(list); printf("Successfully listed users.\n"); //find node user_store_node *bob_node = user_store_find_node(store, bob_public_identity); if (bob_node == NULL) { fprintf(stderr, "ERROR: Failed to find Bob's node.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } printf("Node found.\n"); sodium_mprotect_readonly(bob_node); if ((buffer_compare(&(bob_node->public_identity_key), bob_public_identity) != 0) || (buffer_compare(&(bob_node->private_identity_key), bob_private_identity) != 0) || (buffer_compare(&(bob_node->public_prekeys), bob_public_prekeys) != 0) || (buffer_compare(&(bob_node->private_prekeys), bob_private_prekeys) != 0)) { fprintf(stderr, "ERROR: Bob's data from the user store doesn't match.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } sodium_mprotect_noaccess(bob_node); printf("Data from the node matches.\n"); //remove a user identified by it's key user_store_remove_by_key(store, bob_public_identity); //check the length sodium_mprotect_readonly(store); if (store->length != 2) { fprintf(stderr, "ERROR: User store has incorrect length.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } sodium_mprotect_noaccess(store); printf("Length of the user store matches."); //check the user list list = user_store_list(store); if ((buffer_compare_partial(list, 0, alice_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0) || (buffer_compare_partial(list, crypto_box_PUBLICKEYBYTES, charlie_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0)) { fprintf(stderr, "ERROR: Removing user failed.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); buffer_destroy_from_heap(list); return EXIT_FAILURE; } buffer_destroy_from_heap(list); printf("Successfully removed user.\n"); //readd bob status = user_store_add( store, bob_public_identity, bob_private_identity, bob_public_prekeys, bob_private_prekeys); if (status != 0) { fprintf(stderr, "ERROR: Failed to readd Bob to the user store.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return status; } printf("Successfully readded Bob to the user store.\n"); //now find bob again bob_node = user_store_find_node(store, bob_public_identity); if (bob_node == NULL) { fprintf(stderr, "ERROR: Failed to find Bob's node.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } printf("Bob's node found again.\n"); //remove bob by it's node user_store_remove(store, bob_node); //check the length sodium_mprotect_readonly(store); if (store->length != 2) { fprintf(stderr, "ERROR: User store has incorrect length.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); return EXIT_FAILURE; } sodium_mprotect_noaccess(store); printf("Length of the user store matches."); //check the user list list = user_store_list(store); if ((buffer_compare_partial(list, 0, alice_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0) || (buffer_compare_partial(list, crypto_box_PUBLICKEYBYTES, charlie_public_identity, 0, crypto_box_PUBLICKEYBYTES) != 0)) { fprintf(stderr, "ERROR: Removing user failed.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); user_store_destroy(store); buffer_destroy_from_heap(list); return EXIT_FAILURE; } buffer_destroy_from_heap(list); printf("Successfully removed user.\n"); buffer_clear(alice_private_identity); buffer_clear(alice_private_prekeys); buffer_clear(bob_private_identity); buffer_clear(bob_private_prekeys); buffer_clear(charlie_private_identity); buffer_clear(charlie_private_prekeys); //clear the user store user_store_clear(store); //check the length sodium_mprotect_readonly(store); if (store->length != 0) { fprintf(stderr, "ERROR: User store has incorrect length.\n"); user_store_destroy(store); return EXIT_FAILURE; } printf("Successfully cleared user store.\n"); sodium_mprotect_noaccess(store); user_store_destroy(store); return EXIT_SUCCESS; }
int main(void) { if (sodium_init() == -1) { return -1; } return_status status = return_status_init(); //create buffers //alice keys buffer_t * const alice_public_identity = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t * const alice_private_identity = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t * const alice_public_ephemeral = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t * const alice_private_ephemeral = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t * const alice_shared_secret = buffer_create_on_heap(crypto_generichash_BYTES, crypto_generichash_BYTES); //bobs keys buffer_t * const bob_public_identity = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t * const bob_private_identity = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t * const bob_public_ephemeral = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t * const bob_private_ephemeral = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t * const bob_shared_secret = buffer_create_on_heap(crypto_generichash_BYTES, crypto_generichash_BYTES); printf("Generate Alice's keys -------------------------------------------------------\n\n"); int status_int = 0; //create Alice's identity keypair buffer_create_from_string(alice_string, "Alice"); buffer_create_from_string(identity_string, "identity"); status = generate_and_print_keypair( alice_public_identity, alice_private_identity, alice_string, identity_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Alice' identity keypair."); //create Alice's ephemeral keypair buffer_create_from_string(ephemeral_string, "ephemeral"); status = generate_and_print_keypair( alice_public_ephemeral, alice_private_ephemeral, alice_string, ephemeral_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Alice' ephemeral keypair."); printf("Generate Bob's keys ---------------------------------------------------------\n\n"); //create Bob's identity keypair buffer_create_from_string(bob_string, "Bob"); status = generate_and_print_keypair( bob_public_identity, bob_private_identity, bob_string, identity_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Bob's identity keypair."); //create Bob's ephemeral keypair status = generate_and_print_keypair( bob_public_ephemeral, bob_private_ephemeral, bob_string, ephemeral_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Bob's ephemeral keypair."); printf("Calculate shared secret via Triple Diffie Hellman ---------------------------\n\n"); //Triple Diffie Hellman on Alice's side status = triple_diffie_hellman( alice_shared_secret, alice_private_identity, alice_public_identity, alice_private_ephemeral, alice_public_ephemeral, bob_public_identity, bob_public_ephemeral, true); buffer_clear(alice_private_identity); buffer_clear(alice_private_ephemeral); throw_on_error(KEYGENERATION_FAILED, "Triple Diffie Hellman for Alice failed."); //print Alice's shared secret printf("Alice's shared secret H(DH(A_priv,B0_pub)||DH(A0_priv,B_pub)||DH(A0_priv,B0_pub)):\n"); print_hex(alice_shared_secret); putchar('\n'); //Triple Diffie Hellman on Bob's side status = triple_diffie_hellman( bob_shared_secret, bob_private_identity, bob_public_identity, bob_private_ephemeral, bob_public_ephemeral, alice_public_identity, alice_public_ephemeral, false); buffer_clear(bob_private_identity); buffer_clear(bob_private_ephemeral); throw_on_error(KEYGENERATION_FAILED, "Triple Diffie Hellnan for Bob failed."); //print Bob's shared secret printf("Bob's shared secret H(DH(B0_priv, A_pub)||DH(B_priv, A0_pub)||DH(B0_priv, A0_pub)):\n"); print_hex(bob_shared_secret); putchar('\n'); //compare both shared secrets status_int = buffer_compare(alice_shared_secret, bob_shared_secret); buffer_clear(alice_shared_secret); buffer_clear(bob_shared_secret); if (status_int != 0) { throw(INCORRECT_DATA, "Triple Diffie Hellman didn't produce the same shared secret."); } printf("Both shared secrets match!\n"); cleanup: //alice keys buffer_destroy_from_heap(alice_public_identity); buffer_destroy_from_heap(alice_private_identity); buffer_destroy_from_heap(alice_public_ephemeral); buffer_destroy_from_heap(alice_private_ephemeral); buffer_destroy_from_heap(alice_shared_secret); //bobs keys buffer_destroy_from_heap(bob_public_identity); buffer_destroy_from_heap(bob_private_identity); buffer_destroy_from_heap(bob_public_ephemeral); buffer_destroy_from_heap(bob_private_ephemeral); buffer_destroy_from_heap(bob_shared_secret); on_error { print_errors(&status); } return_status_destroy_errors(&status); return status.status; }
int main(void) { sodium_init(); int status; //create Alice's identity keypair unsigned char alice_public_identity[crypto_box_PUBLICKEYBYTES]; unsigned char alice_private_identity[crypto_box_SECRETKEYBYTES]; status = generate_and_print_keypair( alice_public_identity, alice_private_identity, "Alice", "identity"); if (status != 0) { sodium_memzero(alice_private_identity, sizeof(alice_private_identity)); return status; } //create Alice's ephemeral keypair unsigned char alice_public_ephemeral[crypto_box_PUBLICKEYBYTES]; unsigned char alice_private_ephemeral[crypto_box_SECRETKEYBYTES]; status = generate_and_print_keypair( alice_public_ephemeral, alice_private_ephemeral, "Alice", "ephemeral"); if (status != 0) { sodium_memzero(alice_private_identity, sizeof(alice_private_identity)); sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral)); return status; } //create Bob's identity keypair unsigned char bob_public_identity[crypto_box_PUBLICKEYBYTES]; unsigned char bob_private_identity[crypto_box_SECRETKEYBYTES]; status = generate_and_print_keypair( bob_public_identity, bob_private_identity, "Bob", "identity"); if (status != 0) { sodium_memzero(alice_private_identity, sizeof(alice_private_identity)); sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral)); sodium_memzero(bob_private_identity, sizeof(bob_private_identity)); return status; } //create Bob's ephemeral keypair unsigned char bob_public_ephemeral[crypto_box_PUBLICKEYBYTES]; unsigned char bob_private_ephemeral[crypto_box_SECRETKEYBYTES]; status = generate_and_print_keypair( bob_public_ephemeral, bob_private_ephemeral, "Bob", "ephemeral"); if (status != 0) { sodium_memzero(alice_private_identity, sizeof(alice_private_identity)); sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral)); sodium_memzero(bob_private_identity, sizeof(bob_private_identity)); sodium_memzero(bob_private_ephemeral, sizeof(bob_private_ephemeral)); return status; } //derive Alice's initial root and chain key unsigned char alice_root_key[crypto_secretbox_KEYBYTES]; unsigned char alice_send_chain_key[crypto_secretbox_KEYBYTES]; unsigned char alice_receive_chain_key[crypto_secretbox_KEYBYTES]; unsigned char alice_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; unsigned char alice_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; unsigned char alice_next_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; unsigned char alice_next_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; status = derive_initial_root_chain_and_header_keys( alice_root_key, alice_send_chain_key, alice_receive_chain_key, alice_send_header_key, alice_receive_header_key, alice_next_send_header_key, alice_next_receive_header_key, alice_private_identity, alice_public_identity, bob_public_identity, alice_private_ephemeral, alice_public_ephemeral, bob_public_ephemeral, true); sodium_memzero(alice_private_identity, sizeof(alice_private_identity)); sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral)); if (status != 0) { fprintf(stderr, "ERROR: Failed to derive Alice's initial root and chain key. (%i)\n", status); sodium_memzero(alice_root_key, sizeof(alice_root_key)); sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key)); sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key)); sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key)); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_private_identity, sizeof(bob_private_identity)); sodium_memzero(bob_private_ephemeral, sizeof(bob_private_ephemeral)); return status; } //print Alice's initial root and chain key printf("Alice's initial root key (%zi Bytes):\n", sizeof(alice_root_key)); print_hex(alice_root_key, sizeof(alice_root_key), 30); putchar('\n'); printf("Alice's initial send chain key (%zi Bytes):\n", sizeof(alice_send_chain_key)); print_hex(alice_send_chain_key, sizeof(alice_send_chain_key), 30); putchar('\n'); printf("Alice's initial receive chain key (%zi Bytes):\n", sizeof(alice_receive_chain_key)); print_hex(alice_receive_chain_key, sizeof(alice_receive_chain_key), 30); putchar('\n'); printf("Alice's initial send header key (%zi Bytes):\n", sizeof(alice_send_header_key)); print_hex(alice_send_header_key, sizeof(alice_send_header_key), 30); putchar('\n'); printf("Alice's initial receive header key (%zi Bytes):\n", sizeof(alice_receive_header_key)); print_hex(alice_receive_header_key, sizeof(alice_receive_header_key), 30); printf("Alice's initial next send header key (%zi Bytes):\n", sizeof(alice_next_send_header_key)); print_hex(alice_next_send_header_key, sizeof(alice_next_send_header_key), 30); putchar('\n'); printf("Alice's initial next receive header key (%zi Bytes):\n", sizeof(alice_next_receive_header_key)); print_hex(alice_next_receive_header_key, sizeof(alice_next_receive_header_key), 30); putchar('\n'); //derive Bob's initial root and chain key unsigned char bob_root_key[crypto_secretbox_KEYBYTES]; unsigned char bob_send_chain_key[crypto_secretbox_KEYBYTES]; unsigned char bob_receive_chain_key[crypto_secretbox_KEYBYTES]; unsigned char bob_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; unsigned char bob_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; unsigned char bob_next_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; unsigned char bob_next_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES]; status = derive_initial_root_chain_and_header_keys( bob_root_key, bob_send_chain_key, bob_receive_chain_key, bob_send_header_key, bob_receive_header_key, bob_next_send_header_key, bob_next_receive_header_key, bob_private_identity, bob_public_identity, alice_public_identity, bob_private_ephemeral, bob_public_ephemeral, alice_public_ephemeral, false); sodium_memzero(bob_private_identity, sizeof(bob_private_identity)); sodium_memzero(bob_private_ephemeral, sizeof(bob_private_ephemeral)); if (status != 0) { fprintf(stderr, "ERROR: Failed to derive Bob's initial root and chain key. (%i)", status); sodium_memzero(alice_root_key, sizeof(alice_root_key)); sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key)); sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key)); sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key)); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_root_key, sizeof(bob_root_key)); sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key)); sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key)); sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key)); sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); return status; } //print Bob's initial root and chain key printf("Bob's initial root key (%zi Bytes):\n", sizeof(bob_root_key)); print_hex(bob_root_key, sizeof(bob_root_key), 30); putchar('\n'); printf("Bob's initial send chain key (%zi Bytes):\n", sizeof(bob_send_chain_key)); print_hex(bob_send_chain_key, sizeof(bob_send_chain_key), 30); putchar('\n'); printf("Bob's initial receive chain key (%zi Bytes):\n", sizeof(bob_receive_chain_key)); print_hex(bob_receive_chain_key, sizeof(bob_receive_chain_key), 30); putchar('\n'); printf("Bob's initial send header key (%zi Bytes):\n", sizeof(bob_send_header_key)); print_hex(bob_send_header_key, sizeof(bob_send_header_key), 30); putchar('\n'); printf("Bob's initial receive header key (%zi Bytes):\n", sizeof(bob_receive_header_key)); print_hex(bob_receive_header_key, sizeof(bob_receive_header_key), 30); printf("Bob's initial next send header key (%zi Bytes):\n", sizeof(bob_next_send_header_key)); print_hex(bob_next_send_header_key, sizeof(bob_next_send_header_key), 30); putchar('\n'); printf("Bob's initial next receive header key (%zi Bytes):\n", sizeof(bob_next_receive_header_key)); print_hex(bob_next_receive_header_key, sizeof(bob_next_receive_header_key), 30); putchar('\n'); //compare Alice's and Bob's initial root key if (sodium_memcmp(alice_root_key, bob_root_key, sizeof(alice_root_key)) != 0) { fprintf(stderr, "ERROR: Alice's and Bob's initial root keys don't match.\n"); sodium_memzero(alice_root_key, sizeof(alice_root_key)); sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key)); sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key)); sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key)); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_root_key, sizeof(bob_root_key)); sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key)); sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key)); sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key)); sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); return -10; } printf("Alice's and Bob's initial root keys match.\n"); sodium_memzero(alice_root_key, sizeof(alice_root_key)); sodium_memzero(bob_root_key, sizeof(bob_root_key)); //compare Alice's and Bob's initial chain keys if (sodium_memcmp(alice_send_chain_key, bob_receive_chain_key, sizeof(alice_send_chain_key)) != 0) { fprintf(stderr, "ERROR: Alice's and Bob's initial chain keys don't match.\n"); sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key)); sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key)); sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key)); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key)); sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key)); sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key)); sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); return -10; } printf("Alice's and Bob's initial chain keys match.\n"); sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key)); sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key)); if (sodium_memcmp(alice_receive_chain_key, bob_send_chain_key, sizeof(alice_receive_chain_key)) != 0) { fprintf(stderr, "ERROR: Alice's and Bob's initial chain keys don't match.\n"); sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key)); sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key)); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key)); sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key)); sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); return -10; } printf("Alice's and Bob's initial chain keys match.\n"); //compare Alice's and Bob's initial header keys 1/2 if (sodium_memcmp(alice_send_header_key, bob_receive_header_key, sizeof(alice_send_header_key)) != 0) { fprintf(stderr, "ERROR: Alice's initial send and Bob's initial receive header keys don't match.\n"); sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key)); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key)); sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); return -10; } printf("Alice's initial send and Bob's initial receive header keys match.\n"); sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key)); sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key)); //compare Alice's and Bob's initial header keys 2/2 if (sodium_memcmp(alice_receive_header_key, bob_send_header_key, sizeof(alice_receive_header_key)) != 0) { fprintf(stderr, "ERROR: Alice's initial receive and Bob's initial send header keys don't match.\n"); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); return -10; } printf("Alice's initial receive and Bob's initial send header keys match.\n"); sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key)); sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key)); //compare Alice's and Bob's initial next header keys 1/2 if (sodium_memcmp(alice_next_send_header_key, bob_next_receive_header_key, sizeof(alice_next_send_header_key)) != 0) { fprintf(stderr, "ERROR: Alice's initial next send and Bob's initial next receive header keys don't match.\n"); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); return -10; } printf("Alice's initial next send and Bob's initial next receive header keys match.\n"); sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key)); sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key)); //compare Alice's and Bob's initial next header keys 2/2 if (sodium_memcmp(alice_next_receive_header_key, bob_next_send_header_key, sizeof(alice_next_receive_header_key)) != 0) { fprintf(stderr, "ERROR: Alice's initial next receive and Bob's initial next send header keys don't match.\n"); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); return -10; } printf("Alice's initial next receive and Bob's initial next send header keys match.\n"); sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key)); sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key)); return EXIT_SUCCESS; }
int main(void) { if (sodium_init() == -1) { return -1; } return_status status = return_status_init(); //create key buffers buffer_t *alice_public_ephemeral = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *alice_private_ephemeral = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *bob_public_ephemeral = buffer_create_on_heap(crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); buffer_t *bob_private_ephemeral = buffer_create_on_heap(crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES); buffer_t *previous_root_key = buffer_create_on_heap(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *alice_root_key = buffer_create_on_heap(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *alice_chain_key = buffer_create_on_heap(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *alice_header_key = buffer_create_on_heap(HEADER_KEY_SIZE, HEADER_KEY_SIZE); buffer_t *bob_root_key = buffer_create_on_heap(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *bob_chain_key = buffer_create_on_heap(crypto_secretbox_KEYBYTES, crypto_secretbox_KEYBYTES); buffer_t *bob_header_key = buffer_create_on_heap(HEADER_KEY_SIZE, HEADER_KEY_SIZE); //create Alice's keypair buffer_create_from_string(alice_string, "Alice"); buffer_create_from_string(ephemeral_string, "ephemeral"); status = generate_and_print_keypair( alice_public_ephemeral, alice_private_ephemeral, alice_string, ephemeral_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Alice's ephemeral keypair."); //create Bob's keypair buffer_create_from_string(bob_string, "Bob"); status = generate_and_print_keypair( bob_public_ephemeral, bob_private_ephemeral, bob_string, ephemeral_string); throw_on_error(KEYGENERATION_FAILED, "Failed to generate and print Bob's ephemeral keypair."); //create previous root key if (buffer_fill_random(previous_root_key, crypto_secretbox_KEYBYTES) != 0) { throw(KEYGENERATION_FAILED, "Failed to generate previous root key."); } //print previous root key printf("Previous root key (%zu Bytes):\n", previous_root_key->content_length); print_hex(previous_root_key); putchar('\n'); //derive root and chain key for Alice status = derive_root_next_header_and_chain_keys( alice_root_key, alice_header_key, alice_chain_key, alice_private_ephemeral, alice_public_ephemeral, bob_public_ephemeral, previous_root_key, true); throw_on_error(KEYDERIVATION_FAILED, "Failed to derive root, next header and chain key for Alice."); //print Alice's root and chain key printf("Alice's root key (%zu Bytes):\n", alice_root_key->content_length); print_hex(alice_root_key); printf("Alice's chain key (%zu Bytes):\n", alice_chain_key->content_length); print_hex(alice_chain_key); printf("Alice's header key (%zu Bytes):\n", alice_header_key->content_length); print_hex(alice_header_key); putchar('\n'); //derive root and chain key for Bob status = derive_root_next_header_and_chain_keys( bob_root_key, bob_header_key, bob_chain_key, bob_private_ephemeral, bob_public_ephemeral, alice_public_ephemeral, previous_root_key, false); throw_on_error(KEYDERIVATION_FAILED, "Failed to derive root, next header and chain key for Bob."); //print Bob's root and chain key printf("Bob's root key (%zu Bytes):\n", bob_root_key->content_length); print_hex(bob_root_key); printf("Bob's chain key (%zu Bytes):\n", bob_chain_key->content_length); print_hex(bob_chain_key); printf("Bob's header key (%zu Bytes):\n", bob_header_key->content_length); print_hex(bob_header_key); putchar('\n'); //compare Alice's and Bob's root keys if (buffer_compare(alice_root_key, bob_root_key) == 0) { printf("Alice's and Bob's root keys match.\n"); } else { throw(INCORRECT_DATA, "Alice's and Bob's root keys don't match."); } buffer_clear(alice_root_key); buffer_clear(bob_root_key); //compare Alice's and Bob's chain keys if (buffer_compare(alice_chain_key, bob_chain_key) == 0) { printf("Alice's and Bob's chain keys match.\n"); } else { throw(INCORRECT_DATA, "Alice's and Bob's chain keys don't match."); } //compare Alice's and Bob's header keys if (buffer_compare(alice_header_key, bob_header_key) == 0) { printf("Alice's and Bob's header keys match.\n"); } else { throw(INCORRECT_DATA, "Alice's and Bob's header keys don't match."); } cleanup: buffer_destroy_from_heap_and_null_if_valid(alice_public_ephemeral); buffer_destroy_from_heap_and_null_if_valid(alice_private_ephemeral); buffer_destroy_from_heap_and_null_if_valid(bob_public_ephemeral); buffer_destroy_from_heap_and_null_if_valid(bob_private_ephemeral); buffer_destroy_from_heap_and_null_if_valid(previous_root_key); buffer_destroy_from_heap_and_null_if_valid(alice_root_key); buffer_destroy_from_heap_and_null_if_valid(alice_chain_key); buffer_destroy_from_heap_and_null_if_valid(alice_header_key); buffer_destroy_from_heap_and_null_if_valid(bob_root_key); buffer_destroy_from_heap_and_null_if_valid(bob_chain_key); buffer_destroy_from_heap_and_null_if_valid(bob_header_key); on_error { print_errors(&status); } return_status_destroy_errors(&status); return status.status; }