Skip to content

Commit

Permalink
added support for per-share password protection
Browse files Browse the repository at this point in the history
  • Loading branch information
howech committed Jun 27, 2019
1 parent 7547c74 commit c6e890e
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 5 deletions.
2 changes: 2 additions & 0 deletions slip39.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
typedef struct group_descriptor_struct {
uint8_t threshold;
uint8_t count;
const char **passwords;
} group_descriptor;

typedef struct slip39_share_struct {
Expand Down Expand Up @@ -249,6 +250,7 @@ int combine_mnemonics(
uint32_t mnemonics_words, // number of words in each share
uint32_t mnemonics_shares, // total number of shares
const char *passphrase, // passphrase to unlock master secret
const char **passwords, // passwords protecting shares
uint8_t *buffer, // working space, and place to return secret
uint32_t buffer_length // total amount of working space
);
Expand Down
10 changes: 10 additions & 0 deletions slip39_mnemonics.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ int generate_mnemonics(
share.member_index = j;
share.value = value;

if(groups[i].passwords && groups[i].passwords[j]) {
encrypt_share(&share, groups[i].passwords[j]);
}

unsigned int words = encode_mnemonic(&share, mnemonic, remaining_buffer);

if(word_count == 0) {
Expand All @@ -211,6 +215,7 @@ int generate_mnemonics(
remaining_buffer -= word_count;
share_count++;
mnemonic += word_count;

}
}

Expand Down Expand Up @@ -239,6 +244,7 @@ int combine_mnemonics(
uint32_t mnemonics_words, // number of words in each share
uint32_t mnemonics_shares, // total number of shares
const char *passphrase, // passphrase to unlock master secret
const char **passwords, // passwords for the shares
uint8_t *buffer, // working space, and place to return secret
uint32_t buffer_length // total amount of working space
) {
Expand Down Expand Up @@ -272,6 +278,10 @@ int combine_mnemonics(
return bytes;
}

if(passwords && passwords[i]) {
decrypt_share(&share, passwords[i]);
}

// advance pointers into free buffer
buffer_remaining -= bytes;
secret_length = bytes;
Expand Down
69 changes: 65 additions & 4 deletions test_generate_combine.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "slip39.h"

void test_generate_combine(void);
void test_generate_combine_passwords(void);

void test_generate_combine(void) {
char *test = "abcdefghijklmnopqrstuvwxyz.";
Expand All @@ -11,9 +12,9 @@ void test_generate_combine(void) {
unsigned int words_per_share = 0;

group_descriptor groups[3] = {
{2,3},
{1,1},
{3,5}
{2,3, NULL},
{1,1, NULL},
{3,5, NULL}
};

int shares = generate_mnemonics(3, groups, 3, (unsigned char *)test, secret_length,
Expand Down Expand Up @@ -42,7 +43,7 @@ void test_generate_combine(void) {
mnemonics + 4*words_per_share,
};

int result = combine_mnemonics(recovery_mnemonics, words_per_share, 6, "", buffer, 1024);
int result = combine_mnemonics(recovery_mnemonics, words_per_share, 6, "", NULL, buffer, 1024);

if(result < 0) {
printf("Recovery failed.\n");
Expand All @@ -51,7 +52,67 @@ void test_generate_combine(void) {
printf("%s\n", buffer);
}





void test_generate_combine_passwords(void) {
char *test = "abcdefghijklmnopqrstuvwxyz.";
unsigned int secret_length = strlen(test)+1;

uint16_t mnemonics[1024];
unsigned char buffer[1024];
unsigned int words_per_share = 0;

const char*p1[] = {"a",NULL,"c"};
const char*p3[] = {"e","f", "g", "h", "i"};
group_descriptor groups[3] = {
{2,3, p1},
{1,1, NULL},
{3,5, p3}
};

int shares = generate_mnemonics(3, groups, 3, (unsigned char *)test, secret_length,
"", 0,
&words_per_share, mnemonics, 1024);

if(shares < 0) {
printf("An error occurred during generation.\n");
exit(-1);
}

for(int i=0; i < shares; ++i) {
print_mnemonic(mnemonics + i*words_per_share, words_per_share);
printf("\n");
}


const uint16_t* recovery_mnemonics[] = {
// two from the first group
mnemonics, mnemonics + words_per_share,
// one from the second
mnemonics + 3*words_per_share,
// three from the third
mnemonics + 6*words_per_share,
mnemonics + 5*words_per_share,
mnemonics + 4*words_per_share,
};

const char* passwords[] = {"a", NULL, NULL, "g" ,"f", "e"};

int result = combine_mnemonics(recovery_mnemonics, words_per_share, 6, "", passwords, buffer, 1024);

if(result < 0) {
printf("Recovery failed.\n");
exit(-1);
}
printf("%s\n", buffer);
}



int main(void) {
test_generate_combine();
test_generate_combine_passwords();
return 0;
}
2 changes: 1 addition & 1 deletion vectors_to_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function generate_test(number, name, shares, result) {
//if( strlen(expected_result) > 0 ) {
printf("%s - ", name);
int length = combine_mnemonics(recovery, n, ${shares.length}, "TREZOR", buffer, 32);
int length = combine_mnemonics(recovery, n, ${shares.length}, "TREZOR", NULL, buffer, 32);
if(length > 0) {
bufToHex(buffer, length, result, 256);
Expand Down

0 comments on commit c6e890e

Please sign in to comment.