diff --git a/bsspeke.c b/bsspeke.c index b95bb42aa2d63ba71e15081a98d72ead54c81a35..677c2b7f5f0c7e9b88bffca3199a883b4f20b98e 100644 --- a/bsspeke.c +++ b/bsspeke.c @@ -81,16 +81,20 @@ bsspeke_client_init(bsspeke_client_ctx *ctx, void bsspeke_server_init(bsspeke_server_ctx *ctx, - const char* server_id, const size_t server_id_len + const char* server_id, const size_t server_id_len, + const char* client_id, const size_t client_id_len ) { ctx->server_id = (uint8_t *)server_id; ctx->server_id_len = server_id_len; + + ctx->client_id = (uint8_t *)client_id; + ctx->client_id_len = client_id_len; } void -bsspeke_client_generate_message1 +bsspeke_client_generate_blind ( - bsspeke_login_msg1_t *msg1, + uint8_t blind[32], bsspeke_client_ctx *client ) { debug(DEBUG, "Hashing client's password"); @@ -135,71 +139,81 @@ bsspeke_client_generate_message1 debug(DEBUG, "Multiplying curve point by r"); // 3. Multiply our curve point by r - crypto_x25519_scalarmult(msg1->blind, client->r, curve_point, 256); - print_point("blind", msg1->blind); + crypto_x25519_scalarmult(blind, client->r, curve_point, 256); + print_point("blind", blind); debug(DEBUG, "Done"); - msg1->client_id = client->client_id; return; } void -bsspeke_client_setup_generate_message1 -( - bsspeke_setup_msg1_t *msg1, - bsspeke_client_ctx *client -) { - bsspeke_client_generate_message1(msg1, client); -} - -void -bsspeke_server_setup_generate_message2 +bsspeke_server_blind_salt ( - bsspeke_setup_msg2_t *msg2, - const bsspeke_setup_msg1_t *msg1, - // uint8_t *salt, const size_t salt_len, - bsspeke_user_info_t *user_info, - bsspeke_server_ctx *server_ctx + uint8_t blind_salt[32], + const uint8_t blind[32], + const uint8_t *salt, const size_t salt_len ) { + /* + // FIXME This function no longer generates its own salt! + // We MUST do this before calling the function!!! // We're setting up a new account // So we have to create a new random salt for the user debug(DEBUG, "Generating new salt"); - user_info->salt_len = 32; - //arc4random_buf(user_info->salt, user_info->salt_len); + salt_len = 32; generate_random_bytes(user_info->salt, user_info->salt_len); - print_point("salt", user_info->salt); + */ + print_point("salt", salt); // Hash the salt debug(DEBUG, "Hashing the salt"); uint8_t H_salt[32]; crypto_blake2b_general(H_salt, 32, NULL, 0, - user_info->salt, - user_info->salt_len); + salt, + salt_len); // Use clamp() to ensure we stay on the curve in the multiply below crypto_x25519_clamp(H_salt); print_point("H_salt", H_salt); - // Multiply H(salt) by msg1->blind, save into msg2->blind_salt + // Multiply H(salt) by blind, save into blind_salt debug(DEBUG, "Multiplying H_salt by the user's blind"); - crypto_x25519_scalarmult(msg2->blind_salt, H_salt, msg1->blind, 256); - print_point("blndsalt", msg2->blind_salt); + crypto_x25519_scalarmult(blind_salt, H_salt, blind, 256); + print_point("blndsalt", blind_salt); +} + +void +bsspeke_server_generate_B(const uint8_t P[32], + bsspeke_server_ctx *server) +{ + // Generate random ephemeral private key b, save it in server->b + debug(DEBUG, "Generating ephemeral private key b"); + //arc4random_buf(server->b, 32); + generate_random_bytes(server->b, 32); + crypto_x25519_clamp(server->b); + print_point("b", server->b); + + debug(DEBUG, "Using user's base point P"); + print_point("P", P); + + // Compute public key B = b * P, save it in msg2->B + debug(DEBUG, "Computing ephemeral public key B = b * P"); + crypto_x25519_scalarmult(server->B, server->b, P, 256); + print_point("B", server->B); + } int -bsspeke_client_setup_generate_message3 - ( - bsspeke_setup_msg3_t *msg3, - const bsspeke_setup_msg2_t *msg2, - uint32_t phf_blocks, uint32_t phf_iterations, - bsspeke_client_ctx *client - ) +bsspeke_client_generate_keys_from_password(const uint8_t blind_salt[32], + uint32_t phf_blocks, uint32_t phf_iterations, + bsspeke_client_ctx *client) { // Sanity checks first, before we do any work if( phf_blocks < BSSPEKE_ARGON2_MIN_PHF_BLOCKS ) { + debug(ERROR, "Requested PHF blocks below the minimum"); return -1; } if( phf_iterations < BSSPEKE_ARGON2_MIN_PHF_ITERATIONS ) { + debug(ERROR, "Requested PHF iterations below the minimum"); return -1; } @@ -207,12 +221,10 @@ bsspeke_client_setup_generate_message3 // Multiply the blinded salt by 1/r to get the oblivious salt // Here we rely on Monocypher to do the heavy lifting for us debug(DEBUG, "Removing the blind from the oblivious salt"); - crypto_x25519_inverse(oblivious_salt, client->r, msg2->blind_salt); + crypto_x25519_inverse(oblivious_salt, client->r, blind_salt); print_point("obv_salt", oblivious_salt); // Hash the oblivious salt together with the id's to create the salt for the PHF - uint8_t password_hash[64]; - debug(DEBUG, "Creating the salt for the PHF"); uint8_t phf_salt[32]; { @@ -230,6 +242,7 @@ bsspeke_client_setup_generate_message3 print_point("phf_salt", phf_salt); debug(DEBUG, "Running the PHF to generate p and v"); + uint8_t password_hash[64]; void *work_area; if ((work_area = malloc(phf_blocks * 1024)) == NULL) { return -1; @@ -241,180 +254,71 @@ bsspeke_client_setup_generate_message3 free(work_area); // p || v = pwKdf(password, BlindSalt, idC, idS, settings) - uint8_t *p = &(password_hash[0]); - uint8_t *v = &(password_hash[32]); - // FIXME Should we clamp() v before we multiply??? - crypto_x25519_clamp(v); - print_point("p", p); - print_point("v", v); + uint8_t *tmp_p = &(password_hash[0]); + uint8_t *tmp_v = &(password_hash[32]); + // clamp() v before we do anything else with it + crypto_x25519_clamp(tmp_v); - // Hash p onto the curve to get this user's base point P - //uint8_t P[32]; - debug(DEBUG, "Hashing p onto the curve to get P"); - crypto_hidden_to_curve(msg3->P, p); - print_point("P", msg3->P); + memcpy(client->p, tmp_p, 32); + memcpy(client->v, tmp_v, 32); + crypto_wipe(password_hash, 64); - // Generate our long-term public key V = v * P - debug(DEBUG, "V = v * P"); - crypto_x25519_scalarmult(msg3->V, v, msg3->P, 256); - print_point("V", msg3->V); - - // Send our PHF params so the server can store them for us - msg3->phf_blocks = phf_blocks; - msg3->phf_iterations = phf_iterations; + print_point("p", client->p); + print_point("v", client->v); return 0; } + -void -bsspeke_server_setup_process_message3 +int +bsspeke_client_generate_P_and_V ( - bsspeke_setup_msg3_t *msg3, - bsspeke_user_info_t *user_info, - bsspeke_server_ctx *server + uint8_t P[32], uint8_t V[32], + const uint8_t blind_salt[32], + uint32_t phf_blocks, uint32_t phf_iterations, + bsspeke_client_ctx *client ) { - // Setup Message 3 contains stuff that we need to remember. - // The user info struct is where we store stuff that - // needs to persist across sessions. - memcpy(user_info->P, msg3->P, 32); - memcpy(user_info->V, msg3->V, 32); - user_info->phf_blocks = msg3->phf_blocks; - user_info->phf_iterations = msg3->phf_iterations; -} - -void -bsspeke_client_login_generate_message1 -( - bsspeke_login_msg1_t *msg1, - bsspeke_client_ctx *client -) { - bsspeke_client_generate_message1(msg1, client); -} - -void -bsspeke_server_login_generate_message2(bsspeke_login_msg2_t *msg2, - const bsspeke_login_msg1_t *msg1, - // const uint8_t *salt, const size_t salt_len, - // uint8_t P[32], uint8_t V[32], - // uint32_t phf_blocks, - // uint32_t phf_iterations, - const bsspeke_user_info_t *user_info, - bsspeke_server_ctx *server -) { - // Record the client's id - server->client_id_len = strlen(msg1->client_id); - server->client_id = (uint8_t *)malloc(server->client_id_len + 1); - strncpy(server->client_id, msg1->client_id, server->client_id_len); - printf("Server got msg1 from [%s]\n", (char *)(server->client_id)); - - // Hash the salt - debug(DEBUG, "Hashing the salt"); - uint8_t H_salt[32]; - crypto_blake2b_general(H_salt, 32, - NULL, 0, - user_info->salt, - user_info->salt_len); - // Use clamp() to ensure we stay on the curve in the multiply below - crypto_x25519_clamp(H_salt); - print_point("H_salt", H_salt); - // Multiply H(salt) by msg1->blind, save into msg2->blind_salt - debug(DEBUG, "Multiplying H_salt by the user's blind"); - crypto_x25519_scalarmult(msg2->blind_salt, H_salt, msg1->blind, 256); - print_point("blndsalt", msg2->blind_salt); - - // Generate random ephemeral private key b, save it in ctx->b - debug(DEBUG, "Generating ephemeral private key b"); - //arc4random_buf(server->b, 32); - generate_random_bytes(server->b, 32); - crypto_x25519_clamp(server->b); - print_point("b", server->b); - - debug(DEBUG, "Using user's base point P"); - print_point("P", user_info->P); - - // Compute public key B = b * P, save it in msg2->B - debug(DEBUG, "Computing ephemeral public key B = b * P"); - crypto_x25519_scalarmult(server->B, server->b, user_info->P, 256); - print_point("B", server->B); + int rc = bsspeke_client_generate_keys_from_password(blind_salt, + phf_blocks, phf_iterations, + client); + if( rc != 0 ) { + debug(ERROR, "Password hashing function failed"); + return -1; + } - // Copy the public key into the outgoing message as well - memcpy(msg2->B, server->B, 32); + // Hash p onto the curve to get this user's base point P + //uint8_t P[32]; + debug(DEBUG, "Hashing p onto the curve to get P"); + crypto_hidden_to_curve(P, client->p); + print_point("P", P); - // Copy the PHF params too - msg2->phf_blocks = user_info->phf_blocks; - msg2->phf_iterations = user_info->phf_iterations; + // Generate our long-term public key V = v * P + debug(DEBUG, "V = v * P"); + crypto_x25519_scalarmult(V, client->v, P, 256); + print_point("V", V); - return; + return 0; } int -bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3, - const bsspeke_login_msg2_t *msg2, - bsspeke_client_ctx *client +bsspeke_client_generate_A(const uint8_t blind_salt[32], + uint32_t phf_blocks, uint32_t phf_iterations, + bsspeke_client_ctx *client ) { - // Sanity checks first, before we do any work - if( msg2->phf_blocks < BSSPEKE_ARGON2_MIN_PHF_BLOCKS ) { - debug(ERROR, "phf_blocks is too low. Aborting."); - return -1; - } - if( msg2->phf_iterations < BSSPEKE_ARGON2_MIN_PHF_ITERATIONS ) { - debug(ERROR, "phf_iterations is too low. Aborting."); + int rc = bsspeke_client_generate_keys_from_password(blind_salt, + phf_blocks, phf_iterations, + client); + if( rc != 0 ) { + debug(ERROR, "Password hashing failed"); return -1; } - uint8_t oblivious_salt[32]; - // Multiply the blinded salt by 1/r to get the oblivious salt - // Here we rely on Monocypher to do the heavy lifting for us - debug(DEBUG, "Removing the blind from the oblivious salt"); - crypto_x25519_inverse(oblivious_salt, client->r, msg2->blind_salt); - print_point("obv_salt", oblivious_salt); - - // Hash the oblivious salt together with the id's to create the salt for the PHF - uint8_t password_hash[64]; - - debug(DEBUG, "Creating the salt for the PHF"); - uint8_t phf_salt[32]; - { - crypto_blake2b_ctx hash_ctx; - crypto_blake2b_general_init(&hash_ctx, 32, NULL, 0); - crypto_blake2b_update(&hash_ctx, oblivious_salt, 32); - crypto_blake2b_update(&hash_ctx, - client->client_id, - client->client_id_len); - crypto_blake2b_update(&hash_ctx, - client->server_id, - client->server_id_len); - crypto_blake2b_final(&hash_ctx, phf_salt); - } - print_point("phf_salt", phf_salt); - - debug(DEBUG, "Running the PHF to generate p and v"); - void *work_area; - if ((work_area = malloc(msg2->phf_blocks * 1024)) == NULL) { - debug(ERROR, "Failed to malloc() memory for PHF work area"); - return -1; - } - crypto_argon2i(password_hash, 64, work_area, - msg2->phf_blocks, msg2->phf_iterations, - client->password, client->password_len, - phf_salt, 32); - free(work_area); - - // p || v = pwKdf(password, BlindSalt, idC, idS, settings) - uint8_t *p = &(password_hash[0]); - uint8_t *v = &(password_hash[32]); - // In the setup protocol, we clamped v before using it - // So we should do the same here - crypto_x25519_clamp(v); - print_point("p", p); - print_point("v", v); - // Hash p onto the curve to get this user's base point P uint8_t P[32]; debug(DEBUG, "Hashing p onto the curve to get P"); - crypto_hidden_to_curve(P, p); + crypto_hidden_to_curve(P, client->p); print_point("P", P); // Generate a random ephemeral private key a, store it in ctx->a @@ -425,18 +329,25 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3, print_point("a", client->a); // Generate the ephemeral public key A = a * P, store it in msg3->A debug(DEBUG, "Generating ephemeral public key A = a * P"); - crypto_x25519_scalarmult(msg3->A, client->a, P, 256); - print_point("A", msg3->A); + crypto_x25519_scalarmult(client->A, client->a, P, 256); + print_point("A", client->A); + return 0; +} + +void +bsspeke_client_derive_shared_key(const uint8_t B[32], + bsspeke_client_ctx *client) +{ // Compute the two Diffie-Hellman shared secrets debug(DEBUG, "Computing Diffie-Hellman shared secrets"); // DH shared secret from a * B uint8_t a_B[32]; - crypto_x25519(a_B, client->a, msg2->B); + crypto_x25519(a_B, client->a, B); print_point("a * B", a_B); // DH shared secret from v * B uint8_t v_B[32]; - crypto_x25519(v_B, v, msg2->B); + crypto_x25519(v_B, client->v, B); print_point("v * B", v_B); // Hash everything we know so far to generate our key, save it in ctx->K_c @@ -450,14 +361,19 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3, crypto_blake2b_update(&hash_ctx, client->server_id, client->server_id_len); - crypto_blake2b_update(&hash_ctx, msg3->A, 32); - crypto_blake2b_update(&hash_ctx, msg2->B, 32); + crypto_blake2b_update(&hash_ctx, client->A, 32); + crypto_blake2b_update(&hash_ctx, B, 32); crypto_blake2b_update(&hash_ctx, a_B, 32); crypto_blake2b_update(&hash_ctx, v_B, 32); crypto_blake2b_final(&hash_ctx, client->K_c); } print_point("K_c", client->K_c); +} +void +bsspeke_client_generate_verifier(uint8_t client_verifier[32], + bsspeke_client_ctx *client) +{ // Hash k and the client modifier to get our verifier, save it in msg3->client_verifier debug(DEBUG, "Hashing K_c and modifier to get our verifier"); { @@ -467,29 +383,25 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3, crypto_blake2b_update(&hash_ctx, (uint8_t *)BSSPEKE_VERIFY_CLIENT_MODIFIER, BSSPEKE_VERIFY_CLIENT_MODIFIER_LEN); - crypto_blake2b_final(&hash_ctx, msg3->client_verifier); + crypto_blake2b_final(&hash_ctx, client_verifier); } - print_point("client_v", msg3->client_verifier); - - return 0; + print_point("client_v", client_verifier); } -int -bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4, - const bsspeke_login_msg3_t *msg3, - const bsspeke_user_info_t *user_info, +void +bsspeke_server_derive_shared_key(const uint8_t A[32], + const uint8_t V[32], bsspeke_server_ctx *server ) { // Compute the two Diffie-Hellman shared secrets debug(DEBUG, "Computing Diffie-Hellman shared secrets"); // DH shared secret from b * A uint8_t b_A[32]; - crypto_x25519(b_A, server->b, msg3->A); + crypto_x25519(b_A, server->b, A); print_point("b * A", b_A); // DH shared secret from b * V - //print_point("V", user_info->V); uint8_t b_V[32]; - crypto_x25519(b_V, server->b, user_info->V); + crypto_x25519(b_V, server->b, V); print_point("b * V", b_V); // Hash everything we've learned so far to generate k, save it in ctx->k @@ -503,13 +415,19 @@ bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4, crypto_blake2b_update(&hash_ctx, server->server_id, server->server_id_len); - crypto_blake2b_update(&hash_ctx, msg3->A, 32); + crypto_blake2b_update(&hash_ctx, A, 32); crypto_blake2b_update(&hash_ctx, server->B, 32); crypto_blake2b_update(&hash_ctx, b_A, 32); crypto_blake2b_update(&hash_ctx, b_V, 32); crypto_blake2b_final(&hash_ctx, server->K_s); } print_point("K_s", server->K_s); +} + +int +bsspeke_server_verify_client(uint8_t client_verifier[32], + bsspeke_server_ctx *server +) { // Check that the client's hash is correct // Compute H( k || VERIFY_CLIENT_MODIFIER ) @@ -524,17 +442,24 @@ bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4, BSSPEKE_VERIFY_CLIENT_MODIFIER_LEN); crypto_blake2b_final(&hash_ctx, my_client_verifier); } - print_point("client's", msg3->client_verifier); + print_point("client's", client_verifier); print_point("mine", my_client_verifier); // Compare vs msg3->client_verifier - if( crypto_verify32(msg3->client_verifier, my_client_verifier) != 0 ) { + if( crypto_verify32(client_verifier, my_client_verifier) != 0 ) { debug(ERROR, "Client's verifier doesn't match!"); return -1; } debug(DEBUG, "Client's verifier checks out"); - // Compute our own verifier H( k || VERIFY_SERVER_MODIFIER ), save it in msg4->server_verifier + return 0; +} + +void +bsspeke_server_generate_verifier(uint8_t server_verifier[32], + bsspeke_server_ctx *server +) { + // Compute our own verifier H( k || VERIFY_SERVER_MODIFIER ), save it in server_verifier debug(DEBUG, "Computing server verifier hash"); { crypto_blake2b_ctx hash_ctx; @@ -543,17 +468,14 @@ bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4, crypto_blake2b_update(&hash_ctx, (uint8_t *)BSSPEKE_VERIFY_SERVER_MODIFIER, BSSPEKE_VERIFY_SERVER_MODIFIER_LEN); - crypto_blake2b_final(&hash_ctx, msg4->server_verifier); + crypto_blake2b_final(&hash_ctx, server_verifier); } - print_point("server_v", msg4->server_verifier); - - // If we made it this far, return success - return 0; + print_point("server_v", server_verifier); } int -bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4, - const bsspeke_client_ctx *client +bsspeke_client_verify_server(const uint8_t server_verifier[32], + const bsspeke_client_ctx *client ) { // Compute our own version of the server's verifier hash debug(DEBUG, "Verifying hash from the server"); @@ -568,10 +490,10 @@ bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4, crypto_blake2b_final(&hash_ctx, my_server_verifier); } print_point("mine", my_server_verifier); - print_point("server's", msg4->server_verifier); + print_point("server's", server_verifier); // If the hashes don't match, return failure - if( crypto_verify32(msg4->server_verifier, my_server_verifier) != 0 ) { + if( crypto_verify32(server_verifier, my_server_verifier) != 0 ) { debug(WARN, "Server's hash doesn't match. Aborting."); return -1; } diff --git a/bsspeke.h b/bsspeke.h index 099c8e72e818d53fa75ecc44611e157414ca3cc8..6acc212ea0114ce2c4e7c3f3454196107684dc90 100644 --- a/bsspeke.h +++ b/bsspeke.h @@ -47,9 +47,12 @@ typedef struct { uint8_t r[32]; // Server's ephemeral public key uint8_t B[32]; - // Ephemeral keypair + // Ephemeral keys uint8_t a[32]; - //uint8_t A[32]; + uint8_t A[32]; + // Long term keys + uint8_t v[32]; + uint8_t p[32]; // Session key uint8_t K_c[32]; } bsspeke_client_ctx; @@ -88,6 +91,7 @@ typedef struct { uint8_t blind[32]; } bsspeke_msg1_t; +/* typedef bsspeke_msg1_t bsspeke_setup_msg1_t; typedef struct { @@ -100,8 +104,9 @@ typedef struct { uint32_t phf_blocks; uint32_t phf_iterations; } bsspeke_setup_msg3_t; +*/ - +/* typedef bsspeke_msg1_t bsspeke_login_msg1_t; typedef struct { @@ -119,6 +124,7 @@ typedef struct { typedef struct { uint8_t server_verifier[32]; } bsspeke_login_msg4_t; +*/ void bsspeke_client_init(bsspeke_client_ctx *ctx, @@ -128,71 +134,59 @@ bsspeke_client_init(bsspeke_client_ctx *ctx, void bsspeke_server_init(bsspeke_server_ctx *ctx, - const char* server_id, const size_t server_id_len); + const char* server_id, const size_t server_id_len, + const char* client_id, const size_t client_id_len); void -bsspeke_client_setup_generate_message1 -( - bsspeke_setup_msg1_t *msg1, - bsspeke_client_ctx *client -); +bsspeke_client_generate_blind(uint8_t blind[32], + bsspeke_client_ctx *client); + +void +bsspeke_server_blind_salt(uint8_t blind_salt[32], + const uint8_t blind[32], + const uint8_t *salt, const size_t salt_len); void -bsspeke_server_setup_generate_message2 -( - bsspeke_setup_msg2_t *msg2, - const bsspeke_setup_msg1_t *msg1, - // uint8_t *salt, const size_t salt_len, - bsspeke_user_info_t *user_info, - bsspeke_server_ctx *server_ctx -); +bsspeke_server_generate_B(const uint8_t P[32], + bsspeke_server_ctx *server); int -bsspeke_client_setup_generate_message3 -( - bsspeke_setup_msg3_t *msg3, - const bsspeke_setup_msg2_t *msg2, - uint32_t phf_blocks, uint32_t phf_iterations, - bsspeke_client_ctx *client -); +bsspeke_client_generate_P_and_V(uint8_t P[32], uint8_t V[32], + const uint8_t blind_salt[32], + uint32_t phf_blocks, uint32_t phf_iterations, + bsspeke_client_ctx *client); + +int +bsspeke_client_generate_A(const uint8_t blind_salt[32], + uint32_t phf_blocks, uint32_t phf_iterations, + bsspeke_client_ctx *client); void -bsspeke_server_setup_process_message3 -( - bsspeke_setup_msg3_t *msg3, - bsspeke_user_info_t *user_info, - bsspeke_server_ctx *server -); +bsspeke_client_derive_shared_key(const uint8_t B[32], + bsspeke_client_ctx *client); void -bsspeke_client_login_generate_message1(bsspeke_login_msg1_t *msg1, +bsspeke_client_generate_verifier(uint8_t client_verifier[32], bsspeke_client_ctx *client); + void -bsspeke_server_login_generate_message2(bsspeke_login_msg2_t *msg2, - const bsspeke_login_msg1_t *msg1, - // const uint8_t *salt, const size_t salt_len, - // uint8_t P[32], uint8_t V[32], - // uint32_t phf_blocks, - // uint32_t phf_iterations, - const bsspeke_user_info_t *user, +bsspeke_server_derive_shared_key(const uint8_t A[32], + const uint8_t V[32], bsspeke_server_ctx *server); int -bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3, - const bsspeke_login_msg2_t *msg2, - bsspeke_client_ctx *client_ctx); +bsspeke_server_verify_client(uint8_t client_verifier[32], + bsspeke_server_ctx *server); -int -bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4, - const bsspeke_login_msg3_t *msg3, - const bsspeke_user_info_t *user_info, - bsspeke_server_ctx *server_ctx); +void +bsspeke_server_generate_verifier(uint8_t server_verifier[32], + bsspeke_server_ctx *server); int -bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4, - const bsspeke_client_ctx *client); +bsspeke_client_verify_server(const uint8_t server_verifier[32], + const bsspeke_client_ctx *client); #ifdef __cplusplus } diff --git a/demo.c b/demo.c index b2f053d123779d3bddf85d2f37326e03eb7b5265..e7686d239a330fcfa4dc76b40e7fca83463c6749 100644 --- a/demo.c +++ b/demo.c @@ -36,6 +36,17 @@ int demo_setup(bsspeke_user_info_t *user_info) const char *server_id = "bob.example.com"; const char *password = "P@ssword1"; + // Also, because we got rid of all the + // custom message structs, we need to pretend + // to be the network ferrying messages back + // and forth between the client and server. + // More than that, we have to pretend to be the + // network interface code that marshals and + // unmarshals all of these variables out of + // JSON or whatever. + uint8_t blind[32]; + uint8_t blind_salt[32]; + puts(""); puts("Setup: Initializing client"); bsspeke_client_init(&client, @@ -45,31 +56,36 @@ int demo_setup(bsspeke_user_info_t *user_info) puts("Setup: Initializing server"); bsspeke_server_init(&server, - server_id, strlen(server_id)); - - bsspeke_setup_msg1_t msg1; - bsspeke_setup_msg2_t msg2; - bsspeke_setup_msg3_t msg3; + server_id, strlen(server_id), + client_id, strlen(client_id)); puts(""); puts("Setup: Client generating message 1"); - bsspeke_client_setup_generate_message1(&msg1, &client); + bsspeke_client_generate_blind(blind, &client); puts(""); puts("Setup: Server generating message 2"); - bsspeke_server_setup_generate_message2(&msg2, &msg1, - user_info, - &server); + memset(user_info->salt, '\xff', 32); + user_info->salt_len = 32; + bsspeke_server_blind_salt(blind_salt, + blind, + user_info->salt, user_info->salt_len); puts(""); puts("Setup: Client generating message 3"); - bsspeke_client_setup_generate_message3(&msg3, &msg2, - 100000, 3, - &client); - + user_info->phf_blocks = 100000; + user_info->phf_iterations = 3; + bsspeke_client_generate_P_and_V(user_info->P, + user_info->V, + blind_salt, + user_info->phf_blocks, + user_info->phf_iterations, + &client); + /* puts(""); puts("Setup: Server processing message 3"); bsspeke_server_setup_process_message3(&msg3, user_info, &server); + */ puts(""); puts("Setup: Done"); @@ -98,37 +114,65 @@ int demo_login(bsspeke_user_info_t *user_info) puts("Login: Initializing server"); bsspeke_server_init(&server, - server_id, strlen(server_id)); + server_id, strlen(server_id), + client_id, strlen(client_id)); - bsspeke_login_msg1_t msg1; - bsspeke_login_msg2_t msg2; - bsspeke_login_msg3_t msg3; - bsspeke_login_msg4_t msg4; + // Again we have to pretend to be the network and the + // data marshalling layers + uint8_t blind[32]; + uint8_t blind_salt[32]; + + uint8_t client_verifier[32]; + uint8_t server_verifier[32]; puts(""); puts("Login: Client generating message 1"); - bsspeke_client_login_generate_message1(&msg1, &client); + bsspeke_client_generate_blind(blind, &client); puts(""); puts("Login: Server generating message 2"); - bsspeke_server_login_generate_message2(&msg2, &msg1, - // salt, 32, - // P, V, - // 100000, 3, - user_info, - &server); + bsspeke_server_blind_salt(blind_salt, blind, + user_info->salt, + user_info->salt_len); + bsspeke_server_generate_B(user_info->P, &server); puts(""); puts("Login: Client generating message 3"); - bsspeke_client_login_generate_message3(&msg3, &msg2, &client); + int rc_A = bsspeke_client_generate_A(blind_salt, + user_info->phf_blocks, + user_info->phf_iterations, + &client); + if( rc_A != 0 ) { + puts("Login failed to hash user's password"); + return -1; + } + bsspeke_client_derive_shared_key(server.B, &client); + bsspeke_client_generate_verifier(client_verifier, &client); puts(""); puts("Login: Server generating message 4"); - bsspeke_server_login_generate_message4(&msg4, &msg3, user_info, &server); + bsspeke_server_derive_shared_key(client.A, + user_info->V, + &server); + int rc_s = bsspeke_server_verify_client(client_verifier, + &server); + if( rc_s != 0 ) { + puts("Server failed to verify client."); + puts("LOGIN FAILED"); + return -1; + } + bsspeke_server_generate_verifier(server_verifier, + &server); puts(""); puts("Login: Client verifying message 4"); - bsspeke_client_login_verify_message4(&msg4, &client); + int rc_c = bsspeke_client_verify_server(server_verifier, + &client); + if( rc_c != 0 ) { + puts("Client failed to verify server."); + puts("LOGIN FAILED"); + return -1; + } return 0;