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
9ce778db
Commit
9ce778db
authored
3 years ago
by
Charles Wright
Browse files
Options
Downloads
Patches
Plain Diff
First working version of the demo
parent
2dac201c
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
+84
-28
84 additions, 28 deletions
bsspeke.c
bsspeke.h
+32
-10
32 additions, 10 deletions
bsspeke.h
demo.c
+19
-19
19 additions, 19 deletions
demo.c
with
135 additions
and
57 deletions
bsspeke.c
+
84
−
28
View file @
9ce778db
...
...
@@ -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
;
...
...
This diff is collapsed.
Click to expand it.
bsspeke.h
+
32
−
10
View file @
9ce778db
...
...
@@ -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
This diff is collapsed.
Click to expand it.
demo.c
+
19
−
19
View file @
9ce778db
...
...
@@ -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
);
}
...
...
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