Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
Cbsspeke
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Charles Wright
Cbsspeke
Commits
d079c7d0
Commit
d079c7d0
authored
3 years ago
by
Charles Wright
Browse files
Options
Downloads
Patches
Plain Diff
Refactored the C API to be more granular. This should help with the Python bindings.
parent
025a2c00
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
bsspeke.c
+142
-220
142 additions, 220 deletions
bsspeke.c
bsspeke.h
+42
-48
42 additions, 48 deletions
bsspeke.h
demo.c
+72
-28
72 additions, 28 deletions
demo.c
with
256 additions
and
296 deletions
bsspeke.c
+
142
−
220
View file @
d079c7d0
...
...
@@ -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
;
}
...
...
This diff is collapsed.
Click to expand it.
bsspeke.h
+
42
−
48
View file @
d079c7d0
...
...
@@ -47,9 +47,12 @@ typedef struct {
uint8_t
r
[
32
];
// Server's ephemeral public key
uint8_t
B
[
32
];
// Ephemeral key
pair
// Ephemeral key
s
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
}
...
...
This diff is collapsed.
Click to expand it.
demo.c
+
72
−
28
View file @
d079c7d0
...
...
@@ -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
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment