Beispiel #1
0
int32_t test(int32_t M,int32_t N,int32_t datasize)
{
    int ok = 1, i;
    uint8_t * secret = malloc(datasize);
    uint8_t *shares[255];
    uint8_t *recomb = malloc(datasize);
    uint8_t sharenrs[255],newsharenrs[255];// = (uint8_t *)strdup("0124z89abehtr");
    gfshare_ctx *G;
    gfshare_fill_rand = gfshare_bad_idea_but_fill_rand_using_random;
    for (i=0; i<N; i++)
    {
        sharenrs[i] = i+1;
        shares[i] = malloc(datasize);
    }
    /* Stage 1, make a secret */
    for( i = 0; i < datasize; ++i )
        secret[i] = (rand() & 0xff00) >> 8;
    /* Stage 2, split it N ways with a threshold of M */
    G = gfshare_ctx_init_enc( sharenrs, N, M, datasize );
    gfshare_ctx_enc_setsecret( G, secret );
    for (i=0; i<N; i++)
        gfshare_ctx_enc_getshare( G, i, shares[i] );
    gfshare_ctx_free( G );
    /* Prep the decode shape */
    G = gfshare_ctx_init_dec( sharenrs, N, datasize );
    memset(newsharenrs,0,N);
    int32_t j,r;
    for (i=0; i<M; i++)
    {
        r = rand() % N;
        while ( (j= sharenrs[r]) == 0 || newsharenrs[r] != 0 )
            r = rand() % N;
        newsharenrs[r] = j;
        sharenrs[r] = 0;
    }
    for (i=0; i<N; i++)
    {
        if ( newsharenrs[i] != 0 )
            gfshare_ctx_dec_giveshare( G, i, shares[i] );
        //newsharenrs[i] = sharenrs[i];
    }
    /* Stage 3, attempt a recombination with shares 1 and 2 */
    //sharenrs[2] = 0;
    gfshare_ctx_dec_newshares( G, newsharenrs );
    gfshare_ctx_dec_extract( G, recomb );
    for( i = 0; i < datasize; ++i )
        if( secret[i] != recomb[i] )
            ok = 0;
    printf("M.%-3d N.%-3d ok.%d datalen.%d\n",M,N,ok,datasize);
    free(recomb), free(secret);
    for (i=0; i<N; i++)
        free(shares[i]);
     return ok!=1;
}
Beispiel #2
0
uint8_t *recoverdata(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t datasize,int32_t N)
{
    void *G; int32_t i; uint8_t *recover,recovernrs[255];
    if ( (recover= calloc(1,datasize)) == 0 )
    {
        printf("cards777_recover: unexpected out of memory error\n");
        return(0);
    }
    memset(recovernrs,0,sizeof(recovernrs));
    for (i=0; i<N; i++)
        if ( shares[i] != 0 )
            recovernrs[i] = sharenrs[i];
    G = gfshare_ctx_init_dec(recovernrs,N,datasize);
    for (i=0; i<N; i++)
        if ( shares[i] != 0 )
            gfshare_ctx_dec_giveshare(G,i,shares[i]);
    gfshare_ctx_dec_newshares(G,recovernrs);
    gfshare_ctx_dec_extract(G,recover);
    gfshare_ctx_free(G);
    return(recover);
}
PPH_ERROR pph_unlock_password_data(pph_context *ctx,unsigned int username_count,
                          const uint8 *usernames[], 
                          unsigned int username_lengths[],
                          const uint8 *passwords[]){
  
  
  uint8 share_numbers[MAX_NUMBER_OF_SHARES];
  gfshare_ctx *G;
  unsigned int i;
  uint8 secret[SHARE_LENGTH];
  uint8 salted_password[MAX_USERNAME_LENGTH+MAX_SALT_LENGTH];
  uint8 estimated_digest[DIGEST_LENGTH];
  uint8 estimated_share[SHARE_LENGTH];
  pph_entry *entry; 
  pph_account_node *current_user;
  

  //sanitize the data.
  if(ctx == NULL || usernames == NULL || passwords == NULL || 
      username_lengths == NULL){
    
    return PPH_BAD_PTR;
    
  }

  if(username_count < ctx->threshold){
    
    return PPH_ACCOUNT_IS_INVALID;
    
  }


  // initialize the share numbers
  for(i=0;i<MAX_NUMBER_OF_SHARES;i++){
    share_numbers[i] = 0;
  }
  
  // initialize a recombination context
  G = gfshare_ctx_init_dec( share_numbers, MAX_NUMBER_OF_SHARES-1,
     SHARE_LENGTH-ctx->partial_bytes);


  // traverse our possible users
  current_user=ctx->account_data;
  while(current_user!=NULL){
    // check if each of the provided users is inside the context. We traverse
    // our user list inside the while, and compare against the provided users 
    // inside this for loop.
    for(i = 0; i<username_count;i++){

      //compare the proposed against existing users.
      if(username_lengths[i] == current_user->account.username_length &&
          (!memcmp(usernames[i],current_user->account.username,
            current_user->account.username_length))){

        // this is an existing user
        entry = current_user->account.entries;
        
        // check if he is a threshold account.
        if(entry->share_number != 0){
        
          // if he is a threshold account, we must attempt to reconstruct the
          // shares using their information, traverse his entries
          while(entry!=NULL){

            // calulate the digest given the password.
            memcpy(salted_password,entry->salt,entry->salt_length);
            memcpy(salted_password+entry->salt_length, passwords[i],
                entry->password_length);
            _calculate_digest(estimated_digest,salted_password,
             MAX_SALT_LENGTH + current_user->account.entries->password_length);

            // xor the obtained digest with the polyhashed value to obtain
            // our share.
            _xor_share_with_digest(estimated_share,entry->polyhashed_value,
                estimated_digest,SHARE_LENGTH-ctx->partial_bytes);
         
            // give share to the recombinator. 
            share_numbers[entry->share_number] = entry->share_number+1;
            gfshare_ctx_dec_giveshare(G, entry->share_number,estimated_share);

            // move to the next entry.
            entry = entry->next;
          }
        } 
      }
    } 
    current_user = current_user->next;
  }


  // now we attempt to recombine the secret, we have given him all of the 
  // obtained shares.
  gfshare_ctx_dec_newshares(G, share_numbers);
  gfshare_ctx_dec_extract(G, secret);

  // verify that we got a proper secret back.
  if(check_pph_secret(secret, SIGNATURE_RANDOM_BYTE_LENGTH-ctx->partial_bytes,
        SIGNATURE_HASH_BYTE_LENGTH) != PPH_ERROR_OK){
    
    return PPH_ACCOUNT_IS_INVALID;
    
  }

  // else, we have a correct secret and we will copy it back to the provided
  // context.
  if(ctx->secret == NULL){
    ctx->secret = calloc(sizeof(ctx->secret),SHARE_LENGTH-ctx->partial_bytes);
  }
  memcpy(ctx->secret,secret,SHARE_LENGTH-ctx->partial_bytes);

  // if the share context is not initialized, initialize one with the
  // information we have about our context. 
  if(ctx->share_context == NULL){
    for(i=0;i<MAX_NUMBER_OF_SHARES;i++){
      share_numbers[i]=(unsigned char)i+1;
    }
    ctx->share_context = gfshare_ctx_init_enc( share_numbers,
                                               MAX_NUMBER_OF_SHARES-1,
                                               ctx->threshold,
                                               SHARE_LENGTH-ctx->partial_bytes);
  }
  
  // we have an initialized share context, we set the recombined secret to it 
  // and set the unlock flag to one so it is ready to use.
  gfshare_ctx_enc_setsecret(ctx->share_context, ctx->secret);
  ctx->is_unlocked = true;
  ctx->AES_key = ctx->secret;
  
  return PPH_ERROR_OK;
    
}