Esempio n. 1
1
/**
 * PKCS #1 OAEP decoding
 */
static int OAEP_decode(unsigned char *message,
        unsigned int encoded_bytes, const unsigned char *encoded,
        unsigned int label_bytes, const unsigned char *label) {
  unsigned int i, message_bytes;
  unsigned char DB[RSA_MOD_BYTES - RSA_SHA_BYTES - 1 /* Add MGF1 buffer space */ + 4];
  unsigned char seed[RSA_SHA_BYTES /* Add MGF1 buffer space */ + 4];

  debugValue("OAEP decode: encoded message", encoded, encoded_bytes);

  // First byte of encoded message must be 0x00
  if(encoded[0] != 0x00) {
    debugError("First byte of OAEP encoded message is not 0x00");
    return RSA_ERROR_OAEP_DECODE;
  }

  // Extract maskedDB and maskedSeed
  debugValue("OAEP decode: maskedSeed", encoded + 1, RSA_SHA_BYTES);
  Copy(RSA_SHA_BYTES, DB, encoded + 1 + RSA_SHA_BYTES);
  debugValue("OAEP decode: maskedDB", encoded + 1 + RSA_SHA_BYTES, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  // Finding seed and DB
  MGF1(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB, RSA_SHA_BYTES, seed);
  debugValue("OAEP decode: seedMask", seed, RSA_SHA_BYTES);

  XorAssign(RSA_SHA_BYTES, seed, encoded + 1);
  debugValue("OAEP decode: seed", seed, RSA_SHA_BYTES);

  MGF1(RSA_SHA_BYTES, seed, RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB);
  debugValue("OAEP decode: dbMask", DB, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  XorAssign(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB, encoded + 1 + RSA_SHA_BYTES);
  debugValue("OAEP decode: DB", DB, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  // Compute the hash of l
  debugValue("OAEP decode: label", label, label_bytes);
  SHA(RSA_SHA_BYTES, seed, label_bytes, label);
  debugValue("OAEP decode: hash of label", seed, RSA_SHA_BYTES);

  // Check whether the first RSA_SHA_BYTES bytes of DB equal to lHash
  if (NotEqual(RSA_SHA_BYTES, seed, DB)) {
    debugError("First RSA_SHA_BYTES of DB do not match with hash of label");
    return RSA_ERROR_OAEP_DECODE;
  }

  // Try to locate the message in DB
  i = RSA_SHA_BYTES;
  while ((DB[i] == 0x00) && (DB[i] != 0x01) && (i < (RSA_MOD_BYTES - RSA_SHA_BYTES - 1 - 1))) i++;

  if ((i == (RSA_MOD_BYTES - RSA_SHA_BYTES - 1 - 1)) || (DB[i] != 0x01)) {
    debugError("Failed to locate the message in DB");
    return RSA_ERROR_OAEP_DECODE;
  }

  // Extract the message, starting after 0x01 byte to the end of DB
  message_bytes = RSA_MOD_BYTES - RSA_SHA_BYTES - 1 - 1 - (i + 1) + 1;
  CopyBytes(message_bytes, message, DB + i + 1);
  debugValue("OAEP decode: recovered message", message, message_bytes);

  return message_bytes;
}
Esempio n. 2
0
/**
 * PKCS #1 PSS verification
 */
static int PSS_verify(unsigned int message_bytes, const unsigned char *message,
        unsigned int encoded_bytes, const unsigned char *encoded) {
  unsigned char M[8 + RSA_SHA_BYTES + RSA_SALT_BYTES];
  unsigned char DB[RSA_MOD_BYTES - RSA_SHA_BYTES - 1];

  debugValue("PSS verify: message", message, message_bytes);

  if (encoded_bytes != RSA_MOD_BYTES) {
    return RSA_ERROR_PSS_INCONSISTENT;
  }
  debugValue("PSS verify: encoded message", encoded, encoded_bytes);

  // Verification
  if (encoded[RSA_MOD_BYTES - 1] != 0xbc) {
    return RSA_ERROR_PSS_INCONSISTENT;
  }

  // Extract maskedDB and H
  debugValue("PSS verify: maskedDB", encoded, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);
  Copy(RSA_SHA_BYTES, M + 8, encoded + RSA_MOD_BYTES - RSA_SHA_BYTES - 1);
  debugValue("PSS verify: H", encoded + RSA_MOD_BYTES - RSA_SHA_BYTES - 1, RSA_SHA_BYTES);

  // Compute DB
  MGF1(RSA_SHA_BYTES, M + 8, RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB);
  debugValue("PSS verify: dbMask", DB, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  XorAssign(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB, encoded);
  debugValue("PSS verify: DB", DB, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  if (DB[RSA_MOD_BYTES - RSA_SALT_BYTES - RSA_SHA_BYTES - 2] != 0x01) {
    return RSA_ERROR_PSS_INCONSISTENT;
  }

  // Compute hash of m
  SHA(RSA_SHA_BYTES, M + 8, message_bytes, message);
  debugValue("PSS verify: hash of message", M + 8, RSA_SHA_BYTES);

  Copy(RSA_SALT_BYTES, M + 8 + RSA_SHA_BYTES, DB + RSA_MOD_BYTES - RSA_SALT_BYTES - RSA_SHA_BYTES - 1);
  debugValue("PSS verify: recovered message to be encoded", M, 8 + RSA_SHA_BYTES + RSA_SALT_BYTES);

  SHA(RSA_SHA_BYTES, DB, 8 + RSA_SHA_BYTES + RSA_SALT_BYTES, M);
  debugValue("PSS verify: hash of recovered message to be encoded", DB, RSA_SHA_BYTES);

  if (NotEqual(RSA_SHA_BYTES, encoded + RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB)) {
    debugWarning("PSS verify: verification failed");
    return RSA_ERROR_PSS_INCONSISTENT;
  }

  debugMessage("PSS verify: verification succeeded");
  return RSA_PSS_CONSISTENT;
}
Esempio n. 3
0
/**
 * PKCS #1 OAEP encoding
 */
static int OAEP_encode(unsigned char *encoded,
        unsigned int message_bytes, const unsigned char *message,
        unsigned int label_bytes, const unsigned char *label) {
  unsigned char DB[RSA_MOD_BYTES - RSA_SHA_BYTES - 1 /* Add MGF1 buffer space */ + 4];
  unsigned char seed[RSA_SHA_BYTES /* Add MGF1 buffer space */ + 4];

  // Construct DB
  debugValue("OAEP encode: label", label, label_bytes);
  SHA(RSA_SHA_BYTES, DB, label_bytes, label);
  debugValue("OAEP encode: hash of label", DB, RSA_SHA_BYTES);
  DB[RSA_MOD_BYTES - RSA_SHA_BYTES - message_bytes - 2] = 0x01;
  debugValue("OAEP encode: message", message, message_bytes);
  CopyBytes(message_bytes, DB + RSA_MOD_BYTES - RSA_SHA_BYTES - message_bytes - 1, message);
  debugValue("OAEP encode: DB", DB, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  // Make a random seed
  RandomBytes(seed, RSA_SHA_BYTES);
  debugValue("OAEP encode: seed", seed, RSA_SHA_BYTES);

  // Construct maskedDB and maskedSeed
  MGF1(RSA_SHA_BYTES, seed, RSA_MOD_BYTES - RSA_SHA_BYTES - 1, encoded + 1 + RSA_SHA_BYTES);
  debugValue("OAEP encode: dbMask", encoded + 1 + RSA_SHA_BYTES, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  XorAssign(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB, encoded + 1 + RSA_SHA_BYTES);
  debugValue("OAEP encode: maskedDB", DB, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  MGF1(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB, RSA_SHA_BYTES, encoded + 1);
  debugValue("OAEP encode: seedMask", encoded + 1, RSA_SHA_BYTES);

  XorAssign(RSA_SHA_BYTES, seed, encoded + 1);
  debugValue("OAEP encode: maskedSeed", encoded + 1, RSA_SHA_BYTES);

  Copy(RSA_SHA_BYTES, encoded + 1, seed);
  Copy(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, encoded + 1 + RSA_SHA_BYTES, DB);
  debugValue("OAEP encode: encoded message", encoded, RSA_MOD_BYTES);

  return RSA_MOD_BYTES;
}
Esempio n. 4
0
/**
 * PKCS #1 PSS encoding
 */
static int PSS_encode(unsigned char *encoded,
        unsigned int message_bytes, const unsigned char *message) {
  unsigned char M[8 + RSA_SHA_BYTES + RSA_SALT_BYTES];
  unsigned char DB[RSA_MOD_BYTES - RSA_SHA_BYTES - 1];

  // Compute the hash of m
  debugValue("PSS encode: message", message, message_bytes);
  SHA(RSA_SHA_BYTES, M + 8, message_bytes, message);
  debugValue("PSS encode: hashed message", M + 8, RSA_SHA_BYTES);

  // Generate the salt and construct M
  RandomBytes(M + 8 + RSA_SHA_BYTES, RSA_SALT_BYTES);
  debugValue("PSS encode: salt", M + 8 + RSA_SHA_BYTES, RSA_SALT_BYTES);
  debugValue("PSS encode: message to be encoded", M, 8 + RSA_SHA_BYTES + RSA_SALT_BYTES);

  // Construct DB
  DB[RSA_MOD_BYTES - RSA_SALT_BYTES - RSA_SHA_BYTES - 2] = 0x01;
  Copy(RSA_SALT_BYTES, DB + RSA_MOD_BYTES - RSA_SALT_BYTES - RSA_SHA_BYTES - 1, M + 8 + RSA_SHA_BYTES);
  debugValue("PSS encode: DB", DB, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  // Compute maskedDB
  SHA(RSA_SHA_BYTES, encoded + RSA_MOD_BYTES - RSA_SHA_BYTES - 1, 8 + RSA_SHA_BYTES + RSA_SALT_BYTES, M);
  debugValue("PSS encode: hash of message to be encoded", encoded + RSA_MOD_BYTES - RSA_SHA_BYTES - 1, RSA_SHA_BYTES);

  Copy(RSA_SHA_BYTES, M, encoded + RSA_MOD_BYTES - RSA_SHA_BYTES - 1);
  MGF1(RSA_SHA_BYTES, M, RSA_MOD_BYTES - RSA_SHA_BYTES - 1, encoded);
  debugValue("PSS encode: dbMask", encoded, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  XorAssign(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, DB, encoded);
  debugValue("PSS encode: maskedDB", encoded, RSA_MOD_BYTES - RSA_SHA_BYTES - 1);

  // Construct the encoded message
  Copy(RSA_MOD_BYTES - RSA_SHA_BYTES - 1, encoded, DB);
  encoded[RSA_MOD_BYTES - 1] = 0xbc;
  debugValue("PSS encode: encoded message", encoded, RSA_MOD_BYTES);

  return RSA_MOD_BYTES;
}
Esempio n. 5
0
/*
 PSEC-KEM key encapsulation mechanism

 Return: TRUE if succeed; otherwise FALSE
*/
u8 PSEC_KEM_KEM(
   PSEC_KEM_PUB_KEY    *publicKey,     /* PSEC_KEM public key */
   PSEC_KEM_KEY_ENCAPSULATION *keyEncapsulation,    /* returned keyEncapsulation */
   PSEC_KEM_KEY_MATERIAL *keyMaterial,    /* returned key material */
   EC_PARAM         *E,
   PSEC_KEM_EC_ENCODING_FORMAT format
)
{
mpz_t s, u, res, v;
u8 *s_raw, *u_raw, *t_raw, *mgf_arg_1, *mgf_arg_2, *res_raw, *v_raw, *PEH_raw; 
u8 *EG_raw;
s32 i;
u32 hoLen, uoLen, EGoLen, PEHoLen, qoLen;
EC_POINT h_tilde, g_tilde;

	mpz_init(s);
	mpz_init(u);
	mpz_init(res);
	mpz_init(v);

	hoLen = (publicKey->hLen) >> 3;
	uoLen = (u32)ceil(E->pLen/8.0) + 16;
	keyMaterial->KoLen = (publicKey->outputKeyLen) >> 3;
	qoLen = (u32)ceil(E->qLen/8.0);
	if (format == COMPRESSED)  {
		EGoLen = 1 + qoLen;
		PEHoLen = 1 + qoLen;
	}  else  {
		EGoLen = 1 + 2*qoLen;
		PEHoLen = 1 + 2*qoLen;
	}
	if ((publicKey->pk).inf_id == EC_O) 
		PEHoLen = 1;
	if ((E->P).inf_id == EC_O)
		EGoLen = 1;
#ifdef DEBUG
printf("hoLen = %u\n", hoLen);
printf("uoLen = %u\n", uoLen);
printf("keyMaterial->KoLen = %u\n", keyMaterial->KoLen);
printf("EGoLen = %u\n", EGoLen);
printf("PEHoLen = %u\n", PEHoLen);
#endif
	EC_initPoint ( &h_tilde );
	EC_initPoint ( &g_tilde);

	s_raw = (BYTE *) malloc (hoLen);
	u_raw = (BYTE *) malloc (uoLen);
	t_raw = (BYTE *) malloc (uoLen + keyMaterial->KoLen);
	mgf_arg_1 = (u8 *) malloc (4 + hoLen);
	mgf_arg_2 = (u8 *) malloc (4 + EGoLen + PEHoLen);
	res_raw = (u8 *) malloc (hoLen);
	v_raw = (u8 *) malloc (hoLen);
	PEH_raw = (u8 *) malloc (PEHoLen);
	EG_raw = (u8 *) malloc (EGoLen);

	/* generate s */
	GenerateBytes(s_raw, hoLen, global_prng);
	BYTE2WORD (s, s_raw, hoLen);
#ifdef DEBUG
printf("s = 0x%s\n", mpz_get_str(NULL, 16, s));
printf("\n"); fflush(stdout);
#endif

	/* compute t = MGF1(0 || s) */
	U32TO8_BIG(mgf_arg_1, 0L);
	memcpy(mgf_arg_1+4, s_raw, hoLen);
	MGF1( t_raw, 8 * (uoLen + keyMaterial->KoLen), mgf_arg_1, 4 + hoLen);
#ifdef DEBUG
printf("t = ");
printAsHex(t_raw, uoLen+keyMaterial->KoLen);
printf("\n"); fflush(stdout);
#endif

	/* parse t as t = u || K */
	memcpy( u_raw, t_raw, uoLen );
	BYTE2WORD( u, u_raw, uoLen );
	memcpy( keyMaterial->K_raw, t_raw+uoLen, keyMaterial->KoLen );
#ifdef DEBUG
printf("u = 0x%s\n", mpz_get_str(NULL, 16, u));
printf("keyMaterial = ");
printAsHex(keyMaterial->K_raw, keyMaterial->KoLen);
printf("\n"); fflush(stdout);
#endif

	/* compute h_tilde = u * publicKey->pk */
	EC_Mult( &h_tilde, u, &(publicKey->pk), E );
	ec2os (PEH_raw, &h_tilde, E, format);
#ifdef DEBUG
printf("h_tilde.x = 0x%s\n", mpz_get_str(NULL, 16, h_tilde.x));
printf("h_tilde.y = 0x%s\n", mpz_get_str(NULL, 16, h_tilde.y));
printf("PEH = ");
printAsHex(PEH_raw, PEHoLen);
printf("\n"); fflush(stdout);
#endif

	/* compute g_tilde = u * E->P */
	EC_Mult( &g_tilde, u, &(E->P), E );
#ifdef DEBUG
printf("g_tilde.x = 0x%s\n", mpz_get_str(NULL, 16, g_tilde.x));
printf("g_tilde.y = 0x%s\n", mpz_get_str(NULL, 16, g_tilde.y));
printf("g_tilde.inf_id = %u\n", g_tilde.inf_id);
#endif

    /* convert g_tilde's EC point to an octet string according to P1363 E.2.3.2 */
	ec2os( EG_raw, &g_tilde, E, format);
#ifdef DEBUG
printf("EG = ");
printAsHex(EG_raw, EGoLen);
printf("\n"); fflush(stdout);
#endif

	/* compute res = MGF1( 1 || EG || PEH ) */
	U32TO8_BIG ( mgf_arg_2, 1L );
	memcpy( mgf_arg_2 + 4, EG_raw, EGoLen );
	memcpy( mgf_arg_2 + 4 + EGoLen, PEH_raw, PEHoLen );
	MGF1( res_raw, publicKey->hLen, mgf_arg_2, 4 + EGoLen + PEHoLen);
	BYTE2WORD( res, res_raw, hoLen);
#ifdef DEBUG
printf("res = 0x%s\n", mpz_get_str(NULL, 16, res));
printf("\n"); fflush(stdout);
#endif

	/* compute v = s \xor res */
	mpz_xor(v, s, res);
	WORD2BYTE(v_raw, v, hoLen);
#ifdef DEBUG
printf("v = 0x%s\n", mpz_get_str(NULL, 16, v));
printf("\n"); fflush(stdout);
#endif

	/* output C0 = EG || v */
	memcpy( keyEncapsulation->C0, EG_raw, EGoLen);
	memcpy( keyEncapsulation->C0 + EGoLen, v_raw, hoLen);
#ifdef DEBUG
printf("C0 = ");
printAsHex(keyEncapsulation->C0, keyEncapsulation->C0oLen);
printf("\n"); fflush(stdout);
#endif
	
	/* clean up */
	mpz_clear(s);
	mpz_clear(u);
	mpz_clear(res);
	mpz_clear(v);

	memset(s_raw, 0, hoLen);
	memset(u_raw, 0, uoLen);
	memset(t_raw, 0, uoLen + keyMaterial->KoLen);
	memset(mgf_arg_1, 0, 4+hoLen);
	memset(mgf_arg_2, 0, 4 + EGoLen + PEHoLen);
	memset(res_raw, 0, hoLen);
	memset(v_raw, 0, hoLen);
	memset(PEH_raw, 0, PEHoLen);
	memset(EG_raw, 0, EGoLen);

	free(s_raw);
	free(u_raw);
	free(t_raw);
	free(mgf_arg_1);
	free(mgf_arg_2);
	free(res_raw);
	free(v_raw);
	free(PEH_raw);
	free(EG_raw);

	EC_clearPoint ( &h_tilde );
	EC_clearPoint ( &g_tilde );

	return TRUE;
}