int
rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
	     struct key_data *kd)
{
  mpi P1, Q1, H;
  int r;
  int output_len;

  DEBUG_INFO ("RSA decrypt:");
  DEBUG_WORD ((uint32_t)&output_len);

  mpi_init (&P1, &Q1, &H, NULL);
  rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);

  rsa_ctx.len = msg_len;
  DEBUG_WORD (msg_len);

  mpi_lset (&rsa_ctx.E, 0x10001);
  mpi_read_binary (&rsa_ctx.P, &kd->data[0], KEY_CONTENT_LEN / 2);
  mpi_read_binary (&rsa_ctx.Q, &kd->data[KEY_CONTENT_LEN/2],
		   KEY_CONTENT_LEN / 2);
#if 0 /* Using CRT, we don't use N */
  mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q);
#endif
  mpi_sub_int (&P1, &rsa_ctx.P, 1);
  mpi_sub_int (&Q1, &rsa_ctx.Q, 1);
  mpi_mul_mpi (&H, &P1, &Q1);
  mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H);
  mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1);
  mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1);
  mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P);
  mpi_free (&P1, &Q1, &H, NULL);

  DEBUG_INFO ("RSA decrypt ...");

  r = rsa_pkcs1_decrypt (&rsa_ctx, RSA_PRIVATE, &output_len,
			 input, output, MAX_RES_APDU_DATA_SIZE);
  rsa_free (&rsa_ctx);
  if (r < 0)
    {
      DEBUG_INFO ("fail:");
      DEBUG_SHORT (r);
      return r;
    }
  else
    {
      res_APDU_size = output_len;
      DEBUG_INFO ("done.\r\n");
      GPG_SUCCESS ();
      return 0;
    }
}
示例#2
0
static int
cir_getchar (uint32_t timeout)
{
  uint16_t cir_addr;
#if defined(DEBUG_CIR)
  uint16_t *p;
#endif

#if defined(DEBUG_CIR)
  cirinput_p = cirinput;
#endif

  cir_ll_init ();

  notification = 0;
  wait_usec = timeout;
  chopstx_usec_wait_var (&wait_usec);
  if (notification == 0)
    return -1;

  /* Sleep 200ms to avoid detecting chatter inputs.  */
  chopstx_usec_wait (200 * 1000);

#if defined(DEBUG_CIR)
  DEBUG_INFO ("****\r\n");
  DEBUG_SHORT (intr_ext);
  DEBUG_SHORT (intr_trg);
  DEBUG_SHORT (intr_ovf);
  DEBUG_INFO ("----\r\n");
  for (p = cirinput; p < cirinput_p; p++)
    {
      DEBUG_SHORT (*p);
    }
  DEBUG_INFO ("====\r\n");

  cirinput_p = cirinput;

  DEBUG_INFO ("**** CIR data:");
  DEBUG_WORD (cir_data);
  if (cir_seq > 48)
    {
      DEBUG_SHORT (cir_data_more);
    }
  DEBUG_BYTE (cir_seq);
#endif

  switch (cir_proto)
    {
    case CIR_PROTO_RC5:
      cir_data &= 0x003f;
      goto err;
    case CIR_PROTO_RC6:
      cir_addr = cir_data >> 8; /* in case of cir_seq == 16.  32??? */
      cir_data &= 0x00ff;
      return find_char_codetable (cir_data, cir_codetable_dell_mr425);
    case CIR_PROTO_NEC:
      cir_addr = cir_data&0xffff;
      if (cir_addr == CIR_ADDR_TOSHIBA_REGZA)
	{
	  cir_data = (cir_data >> 16) & 0x00ff;
	  return find_char_codetable (cir_data, cir_codetable_regza);
	}
      else
	goto err;