static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int password_shares_threshold, int password_shares_total) { int r, i; BIGNUM prime; BIGNUM secret; char buf[64]; char hex[64]; int l; secret_share_t *shares = NULL; secret_share_t *sp; u8 rngseed[16]; printf( "\nThe DKEK will be enciphered using a randomly generated 64 bit password.\n"); printf( "This password is split using a (%i-of-%i) threshold scheme.\n\n", password_shares_threshold, password_shares_total); printf( "Please keep the generated and encrypted DKEK file in a safe location. We also recommend \n"); printf( "to keep a paper printout, in case the electronic version becomes unavailable. A printable version\n"); printf( "of the file can be generated using \"openssl base64 -in <filename>\".\n"); printf("\n\nPress <enter> to continue"); waitForEnterKeyPressed(); *pwd = calloc(1, 8); *pwdlen = 8; r = sc_get_challenge(card, *pwd, 8); if (r < 0) { printf("Error generating random key failed with ", sc_strerror(r)); OPENSSL_cleanse(pwd, *pwdlen); free(pwd); return r; } **pwd |= 0x80; /* * Initialize prime and secret */ BN_init(&prime); BN_init(&secret); /* * Encode the secret value */ BN_bin2bn(*pwd, *pwdlen, &secret); /* * Generate seed and calculate a prime depending on the size of the secret */ r = sc_get_challenge(card, rngseed, 16); if (r < 0) { printf("Error generating random seed failed with ", sc_strerror(r)); OPENSSL_cleanse(pwd, *pwdlen); free(pwd); return r; } generatePrime(&prime, &secret, password_shares_total, rngseed); // Allocate data buffer for the generated shares shares = malloc(password_shares_total * sizeof(secret_share_t)); createShares(&secret, password_shares_threshold, password_shares_total, prime, shares); sp = shares; for (i = 0; i < password_shares_total; i++) { clearScreen(); printf("Press <enter> to display key share %i of %i\n\n", i + 1, password_shares_total); waitForEnterKeyPressed(); clearScreen(); printf("Share %i of %i\n\n", i + 1, password_shares_total); l = BN_bn2bin(&prime, buf); sc_bin_to_hex(buf, l, hex, 64, ':'); printf("\nPrime : %s\n", hex); printf("Share ID : %s\n", BN_bn2dec(&(sp->x))); l = BN_bn2bin(&(sp->y), buf); sc_bin_to_hex(buf, l, hex, 64, ':'); printf("Share value : %s\n", hex); printf("\n\nPlease note ALL values above and press <enter> when finished"); waitForEnterKeyPressed(); sp++; } clearScreen(); cleanUpShares(shares, password_shares_total); BN_clear_free(&prime); BN_clear_free(&secret); return 0; }
static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_password_shares) { int r, i; BIGNUM *prime; BIGNUM *secret; BIGNUM *p; char inbuf[64]; unsigned char bin[64]; size_t binlen = 0; unsigned char *ip; secret_share_t *shares = NULL; secret_share_t *sp; if (num_of_password_shares < 2) { fprintf(stderr, "--pwd-shares-total must 2 or larger\n"); return -1; } // Allocate data buffer for the shares shares = malloc(num_of_password_shares * sizeof(secret_share_t)); if (!shares) return -1; /* * Initialize prime and secret */ prime = BN_new(); secret = BN_new(); printf("\nDeciphering the DKEK for import into the SmartCard-HSM requires %i key custodians", num_of_password_shares); printf("\nto present their share. Only the first key custodian needs to enter the public prime."); printf("\nPlease remember to present the share id as well as the share value."); printf("\n\nPlease enter prime: "); memset(inbuf, 0, sizeof(inbuf)); if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) { fprintf(stderr, "Input aborted\n"); free(shares); return -1; } binlen = 64; sc_hex_to_bin(inbuf, bin, &binlen); BN_bin2bn(bin, binlen, prime); sp = shares; for (i = 0; i < num_of_password_shares; i++) { clearScreen(); printf("Press <enter> to enter share %i of %i\n\n", i + 1, num_of_password_shares); waitForEnterKeyPressed(); clearScreen(); sp->x = BN_new(); sp->y = BN_new(); printf("Share %i of %i\n\n", i + 1, num_of_password_shares); printf("Please enter share ID: "); memset(inbuf, 0, sizeof(inbuf)); if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) { fprintf(stderr, "Input aborted\n"); free(shares); return -1; } p = (sp->x); BN_hex2bn(&p, inbuf); printf("Please enter share value: "); memset(inbuf, 0, sizeof(inbuf)); if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) { fprintf(stderr, "Input aborted\n"); free(shares); return -1; } binlen = 64; sc_hex_to_bin(inbuf, bin, &binlen); BN_bin2bn(bin, binlen, (sp->y)); sp++; } clearScreen(); r = reconstructSecret(shares, num_of_password_shares, prime, secret); if (r < 0) { printf("\nError during reconstruction of secret. Wrong shares?\n"); cleanUpShares(shares, num_of_password_shares); return r; } /* * Encode the secret value */ ip = (unsigned char *) inbuf; *pwdlen = BN_bn2bin(secret, ip); *pwd = calloc(1, *pwdlen); if (*pwd) { memcpy(*pwd, ip, *pwdlen); } cleanUpShares(shares, num_of_password_shares); BN_clear_free(prime); BN_clear_free(secret); return *pwd ? 0 : -1; }
static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_password_shares) { int r, i; BIGNUM prime; BIGNUM secret; BIGNUM *p; char inbuf[64]; char bin[64]; int binlen = 0; char *ip; secret_share_t *shares = NULL; secret_share_t *sp; /* * Initialize prime and secret */ BN_init(&prime); BN_init(&secret); // Allocate data buffer for the shares shares = malloc(num_of_password_shares * sizeof(secret_share_t)); printf("\nDeciphering the DKEK for import into the SmartCard-HSM requires %i key custodians", num_of_password_shares); printf("\nto present their share. Only the first key custodian needs to enter the public prime."); printf("\nPlease remember to present the share id as well as the share value."); printf("\n\nPlease enter prime: "); memset(inbuf, 0, sizeof(inbuf)); fgets(inbuf, sizeof(inbuf), stdin); binlen = 64; sc_hex_to_bin(inbuf, bin, &binlen); BN_bin2bn(bin, binlen, &prime); sp = shares; for (i = 0; i < num_of_password_shares; i++) { clearScreen(); printf("Press <enter> to enter share %i of %i\n\n", i + 1, num_of_password_shares); waitForEnterKeyPressed(); clearScreen(); BN_init(&(sp->x)); BN_init(&(sp->y)); printf("Share %i of %i\n\n", i + 1, num_of_password_shares); printf("Please enter share ID: "); memset(inbuf, 0, sizeof(inbuf)); fgets(inbuf, sizeof(inbuf), stdin); p = &(sp->x); BN_hex2bn(&p, inbuf); printf("Please enter share value: "); memset(inbuf, 0, sizeof(inbuf)); fgets(inbuf, sizeof(inbuf), stdin); binlen = 64; sc_hex_to_bin(inbuf, bin, &binlen); BN_bin2bn(bin, binlen, &(sp->y)); sp++; } clearScreen(); r = reconstructSecret(shares, num_of_password_shares, prime, &secret); if (r < 0) { printf("\nError during reconstruction of secret. Wrong shares?\n"); return r; } /* * Encode the secret value */ ip = inbuf; *pwdlen = BN_bn2bin(&secret, ip); *pwd = calloc(1, *pwdlen); memcpy(*pwd, ip, *pwdlen); cleanUpShares(shares, num_of_password_shares); BN_clear_free(&prime); BN_clear_free(&secret); return 0; }
static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int password_shares_threshold, int password_shares_total) { int r, i; BIGNUM *prime; BIGNUM *secret; unsigned char buf[64]; char hex[64]; int l; secret_share_t *shares = NULL; secret_share_t *sp; u8 rngseed[16]; if ((password_shares_threshold == -1) || (password_shares_total == -1)) { fprintf(stderr, "Must specify both, --pwd-shares-total and --pwd-shares-threshold\n"); return -1; } if (password_shares_total < 3) { fprintf(stderr, "--pwd-shares-total must be 3 or larger\n"); return -1; } if (password_shares_threshold < 2) { fprintf(stderr, "--pwd-shares-threshold must 2 or larger\n"); return -1; } if (password_shares_threshold > password_shares_total) { fprintf(stderr, "--pwd-shares-threshold must be smaller or equal to --pwd-shares-total\n"); return -1; } printf( "\nThe DKEK will be enciphered using a randomly generated 64 bit password.\n"); printf( "This password is split using a (%i-of-%i) threshold scheme.\n\n", password_shares_threshold, password_shares_total); printf( "Please keep the generated and encrypted DKEK file in a safe location. We also recommend \n"); printf( "to keep a paper printout, in case the electronic version becomes unavailable. A printable version\n"); printf( "of the file can be generated using \"openssl base64 -in <filename>\".\n"); printf("\n\nPress <enter> to continue"); waitForEnterKeyPressed(); *pwd = calloc(1, 8); *pwdlen = 8; r = sc_get_challenge(card, (unsigned char *)*pwd, 8); if (r < 0) { printf("Error generating random key failed with %s", sc_strerror(r)); OPENSSL_cleanse(*pwd, *pwdlen); free(*pwd); return r; } **pwd &= 0x7F; // Make sure the bit size of the secret is not bigger than 63 bits /* * Initialize prime and secret */ prime = BN_new(); secret = BN_new(); /* * Encode the secret value */ BN_bin2bn((unsigned char *)*pwd, *pwdlen, secret); /* * Generate seed and calculate a prime depending on the size of the secret */ r = sc_get_challenge(card, rngseed, SEED_LENGTH); if (r < 0) { printf("Error generating random seed failed with %s", sc_strerror(r)); OPENSSL_cleanse(*pwd, *pwdlen); free(*pwd); return r; } r = generatePrime(prime, secret, 64, rngseed, SEED_LENGTH); if (r < 0) { printf("Error generating valid prime number. Please try again."); OPENSSL_cleanse(*pwd, *pwdlen); free(*pwd); return r; } // Allocate data buffer for the generated shares shares = malloc(password_shares_total * sizeof(secret_share_t)); createShares(secret, password_shares_threshold, password_shares_total, prime, shares); sp = shares; for (i = 0; i < password_shares_total; i++) { clearScreen(); printf("Press <enter> to display key share %i of %i\n\n", i + 1, password_shares_total); waitForEnterKeyPressed(); clearScreen(); printf("Share %i of %i\n\n", i + 1, password_shares_total); l = BN_bn2bin(prime, buf); sc_bin_to_hex(buf, l, hex, 64, ':'); printf("\nPrime : %s\n", hex); printf("Share ID : %s\n", BN_bn2dec((sp->x))); l = BN_bn2bin((sp->y), buf); sc_bin_to_hex(buf, l, hex, 64, ':'); printf("Share value : %s\n", hex); printf("\n\nPlease note ALL values above and press <enter> when finished"); waitForEnterKeyPressed(); sp++; } clearScreen(); cleanUpShares(shares, password_shares_total); BN_clear_free(prime); BN_clear_free(secret); return 0; }