Skip to content
Snippets Groups Projects
Commit 9ce778db authored by Charles Wright's avatar Charles Wright
Browse files

First working version of the demo

parent 2dac201c
No related branches found
No related tags found
No related merge requests found
......@@ -127,6 +127,8 @@ bsspeke_client_generate_message1
crypto_x25519_scalarmult(msg1->blind, client->r, curve_point, 256);
print_point("blind", msg1->blind);
debug(DEBUG, "Done");
msg1->client_id = client->client_id;
return;
}
......@@ -144,20 +146,25 @@ bsspeke_server_setup_generate_message2
(
bsspeke_setup_msg2_t *msg2,
const bsspeke_setup_msg1_t *msg1,
uint8_t *salt, const size_t salt_len,
// uint8_t *salt, const size_t salt_len,
bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server_ctx
)
{
// We're setting up a new account
// So we have to create a new random salt for the user
debug(DEBUG, "Generating new salt");
arc4random_buf(salt, salt_len);
print_point("salt", salt);
user_info->salt_len = 32;
arc4random_buf(user_info->salt, user_info->salt_len);
print_point("salt", user_info->salt);
// Hash the salt
debug(DEBUG, "Hashing the salt");
uint8_t H_salt[32];
crypto_blake2b_general(H_salt, 32, NULL, 0, salt, salt_len);
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);
......@@ -240,9 +247,29 @@ bsspeke_client_setup_generate_message3
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;
return 0;
}
void
bsspeke_server_setup_process_message3
(
bsspeke_setup_msg3_t *msg3,
bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server
)
{
// 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
......@@ -256,16 +283,26 @@ bsspeke_client_login_generate_message1
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 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, salt, salt_len);
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);
......@@ -280,20 +317,20 @@ bsspeke_server_login_generate_message2(bsspeke_login_msg2_t *msg2,
crypto_x25519_clamp(server->b);
print_point("b", server->b);
debug(DEBUG, "Using client's base point P");
print_point("P", P);
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, P, 256);
crypto_x25519_scalarmult(server->B, server->b, user_info->P, 256);
print_point("B", server->B);
// Copy the public key into the outgoing message as well
memcpy(msg2->B, server->B, 32);
// Copy the PHF params too
msg2->phf_blocks = phf_blocks;
msg2->phf_iterations = phf_iterations;
msg2->phf_blocks = user_info->phf_blocks;
msg2->phf_iterations = user_info->phf_iterations;
return;
}
......@@ -426,86 +463,105 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
int
bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4,
const bsspeke_login_msg3_t *msg3,
bsspeke_server_ctx *server_ctx
const bsspeke_user_info_t *user_info,
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_ctx->b, msg3->A);
crypto_x25519(b_A, server->b, msg3->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_ctx->b, server_ctx->V);
crypto_x25519(b_V, server->b, user_info->V);
print_point("b * V", b_V);
// Hash everything we've learned so far to generate k, save it in ctx->k
debug(DEBUG, "Hashing state so far to generate K_s");
{
crypto_blake2b_ctx hash_ctx;
crypto_blake2b_general_init(&hash_ctx, 32, NULL, 0);
crypto_blake2b_update(&hash_ctx,
server_ctx->client_id,
server_ctx->client_id_len);
server->client_id,
server->client_id_len);
crypto_blake2b_update(&hash_ctx,
server_ctx->server_id,
server_ctx->server_id_len);
server->server_id,
server->server_id_len);
crypto_blake2b_update(&hash_ctx, msg3->A, 32);
crypto_blake2b_update(&hash_ctx, server_ctx->B, 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_ctx->K_s);
crypto_blake2b_final(&hash_ctx, server->K_s);
}
print_point("K_s", server->K_s);
// Check that the client's hash is correct
// Compute H( k || VERIFY_CLIENT_MODIFIER )
debug(DEBUG, "Checking client's verifier hash");
uint8_t my_client_verifier[32];
{
crypto_blake2b_ctx hash_ctx;
crypto_blake2b_general_init(&hash_ctx, 32, NULL, 0);
crypto_blake2b_update(&hash_ctx, server_ctx->K_s, 32);
crypto_blake2b_update(&hash_ctx, server->K_s, 32);
crypto_blake2b_update(&hash_ctx,
(uint8_t *)BSSPEKE_VERIFY_CLIENT_MODIFIER,
BSSPEKE_VERIFY_CLIENT_MODIFIER_LEN);
crypto_blake2b_final(&hash_ctx, my_client_verifier);
}
print_point("client's", msg3->client_verifier);
print_point("mine", my_client_verifier);
// Compare vs msg3->client_verifier
if( crypto_verify32(msg3->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
debug(DEBUG, "Computing server verifier hash");
{
crypto_blake2b_ctx hash_ctx;
crypto_blake2b_general_init(&hash_ctx, 32, NULL, 0);
crypto_blake2b_update(&hash_ctx, server_ctx->K_s, 32);
crypto_blake2b_update(&hash_ctx, server->K_s, 32);
crypto_blake2b_update(&hash_ctx,
(uint8_t *)BSSPEKE_VERIFY_SERVER_MODIFIER,
BSSPEKE_VERIFY_SERVER_MODIFIER_LEN);
crypto_blake2b_final(&hash_ctx, msg4->server_verifier);
}
print_point("server_v", msg4->server_verifier);
// If we made it this far, return success
return 0;
}
int
bsspeke_client_verify_message4(const bsspeke_login_msg4_t *msg4,
const bsspeke_client_ctx *client_ctx
bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4,
const bsspeke_client_ctx *client
) {
// Compute our own version of the server's verifier hash
debug(DEBUG, "Verifying hash from the server");
uint8_t my_server_verifier[32];
{
crypto_blake2b_ctx hash_ctx;
crypto_blake2b_general_init(&hash_ctx, 32, NULL, 0);
crypto_blake2b_update(&hash_ctx, client_ctx->K_c, 32);
crypto_blake2b_update(&hash_ctx, client->K_c, 32);
crypto_blake2b_update(&hash_ctx,
(uint8_t *)BSSPEKE_VERIFY_SERVER_MODIFIER,
BSSPEKE_VERIFY_SERVER_MODIFIER_LEN);
crypto_blake2b_final(&hash_ctx, my_server_verifier);
}
print_point("mine", my_server_verifier);
print_point("server's", msg4->server_verifier);
// If the hashes don't match, return failure
if( crypto_verify32(msg4->server_verifier, my_server_verifier) != 0 ) {
debug(WARN, "Server's hash doesn't match. Aborting.");
return -1;
}
debug(DEBUG, "Server's hash checks out. SUCCESS!");
// Otherwise, return success
return 0;
......
......@@ -57,8 +57,8 @@ typedef struct {
uint8_t *client_id; // Client's identifier (eg Matrix user_id)
size_t client_id_len;
uint8_t P[32]; // Base point for the user
uint8_t V[32]; // User's long-term public key
//uint8_t P[32]; // Base point for the user
//uint8_t V[32]; // User's long-term public key
uint8_t b[32]; // Ephemeral private key
uint8_t B[32]; // Ephemeral public key
......@@ -68,6 +68,17 @@ typedef struct {
uint8_t K_s[32]; // Session key
} bsspeke_server_ctx;
typedef struct {
uint8_t salt[32];
size_t salt_len;
uint8_t P[32];
uint8_t V[32];
uint32_t phf_blocks;
uint32_t phf_iterations;
} bsspeke_user_info_t;
typedef struct {
char *client_id;
uint8_t blind[32];
......@@ -128,7 +139,8 @@ bsspeke_server_setup_generate_message2
(
bsspeke_setup_msg2_t *msg2,
const bsspeke_setup_msg1_t *msg1,
uint8_t *salt, const size_t salt_len,
// uint8_t *salt, const size_t salt_len,
bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server_ctx
);
......@@ -141,6 +153,14 @@ bsspeke_client_setup_generate_message3
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
);
void
bsspeke_client_login_generate_message1(bsspeke_login_msg1_t *msg1,
bsspeke_client_ctx *client);
......@@ -148,11 +168,12 @@ bsspeke_client_login_generate_message1(bsspeke_login_msg1_t *msg1,
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,
bsspeke_server_ctx *server_ctx);
// 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_ctx *server);
int
bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
......@@ -162,10 +183,11 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
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);
int
bsspeke_client_verify_message4(const bsspeke_login_msg4_t *msg4,
const bsspeke_client_ctx *client_ctx);
bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4,
const bsspeke_client_ctx *client);
#endif
......@@ -4,9 +4,7 @@
#include "bsspeke.h"
int demo_setup(uint8_t salt[32],
uint8_t P[32],
uint8_t V[32])
int demo_setup(bsspeke_user_info_t *user_info)
{
bsspeke_client_ctx client;
bsspeke_server_ctx server;
......@@ -40,7 +38,7 @@ int demo_setup(uint8_t salt[32],
puts("");
puts("Setup: Server generating message 2");
bsspeke_server_setup_generate_message2(&msg2, &msg1,
salt, 32,
user_info,
&server);
puts("");
......@@ -50,9 +48,8 @@ int demo_setup(uint8_t salt[32],
&client);
puts("");
puts("Setup: Saving parameters from setup");
memcpy(P, msg3.P, 32);
memcpy(V, msg3.V, 32);
puts("Setup: Server processing message 3");
bsspeke_server_setup_process_message3(&msg3, user_info, &server);
puts("");
puts("Setup: Done");
......@@ -60,9 +57,7 @@ int demo_setup(uint8_t salt[32],
return 0;
}
int demo_login(uint8_t salt[32],
uint8_t P[32],
uint8_t V[32])
int demo_login(bsspeke_user_info_t *user_info)
{
bsspeke_client_ctx client;
bsspeke_server_ctx server;
......@@ -97,15 +92,23 @@ int demo_login(uint8_t salt[32],
puts("");
puts("Login: Server generating message 2");
bsspeke_server_login_generate_message2(&msg2, &msg1,
salt, 32,
P, V,
100000, 3,
// salt, 32,
// P, V,
// 100000, 3,
user_info,
&server);
puts("");
puts("Login: Client generating message 3");
bsspeke_client_login_generate_message3(&msg3, &msg2, &client);
puts("");
puts("Login: Server generating message 4");
bsspeke_server_login_generate_message4(&msg4, &msg3, user_info, &server);
puts("");
puts("Login: Client verifying message 4");
bsspeke_client_login_verify_message4(&msg4, &client);
return 0;
......@@ -114,19 +117,16 @@ int demo_login(uint8_t salt[32],
int main(int argc, char *argv[])
{
// Here we're pretending to be the server's long-term storage
// It needs to know the salt, V, and P for each registered user
uint8_t salt[32];
uint8_t V[32];
uint8_t P[32];
bsspeke_user_info_t user_info;
int rc = 0;
if( (rc = demo_setup(salt, P, V)) != 0 ) {
if( (rc = demo_setup(&user_info)) != 0 ) {
puts("Setup failed :(");
exit(-1);
}
if( (rc = demo_login(salt, P, V)) != 0 ) {
if( (rc = demo_login(&user_info)) != 0 ) {
puts("Login failed :(");
exit(-1);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment