PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
+ PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA1),
/* signature verification schemes */
#if GCRYPT_VERSION_NUMBER >= 0x010700
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
+ PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA1),
/* random numbers */
PLUGIN_REGISTER(RNG, gcrypt_rng_create),
PLUGIN_PROVIDE(RNG, RNG_WEAK),
{
gcry_error_t err;
gcry_sexp_t in, out;
- chunk_t padded;
- u_char *pos = NULL;;
+ chunk_t label = chunk_empty, decrypted;
+ u_char *sexp;
- if (scheme != ENCRYPT_RSA_PKCS1)
+ switch (scheme)
{
- DBG1(DBG_LIB, "encryption scheme %N not supported",
- encryption_scheme_names, scheme);
- return FALSE;
+ case ENCRYPT_RSA_PKCS1:
+ sexp = "(enc-val(flags pkcs1)(rsa(a %b)))";
+ break;
+ case ENCRYPT_RSA_OAEP_SHA1:
+ sexp = "(enc-val(flags oaep)(rsa(a %b)))";
+ break;
+ default:
+ DBG1(DBG_LIB, "encryption scheme %N not supported",
+ encryption_scheme_names, scheme);
+ return FALSE;
}
- err = gcry_sexp_build(&in, NULL, "(enc-val(flags)(rsa(a %b)))",
- encrypted.len, encrypted.ptr);
+
+ if (scheme == ENCRYPT_RSA_OAEP_SHA1 && params != NULL)
+ {
+ label = *(chunk_t *)params;
+ if (label.len > 0)
+ {
+ DBG1(DBG_LIB, "RSA OAEP decryption with a label not supported");
+ return FALSE;
+ }
+ }
+
+ err = gcry_sexp_build(&in, NULL, sexp, encrypted.len, encrypted.ptr);
if (err)
{
DBG1(DBG_LIB, "building decryption S-expression failed: %s",
gpg_strerror(err));
return FALSE;
}
+
err = gcry_pk_decrypt(&out, in, this->key);
gcry_sexp_release(in);
if (err)
{
- DBG1(DBG_LIB, "decrypting pkcs1 data failed: %s", gpg_strerror(err));
+ DBG1(DBG_LIB, "RSA decryption failed: %s", gpg_strerror(err));
return FALSE;
}
- padded.ptr = (u_char*)gcry_sexp_nth_data(out, 1, &padded.len);
- /* result is padded, but gcrypt strips leading zero:
- * 00 | 02 | RANDOM | 00 | DATA */
- if (padded.ptr && padded.len > 2 && padded.ptr[0] == 0x02)
- {
- pos = memchr(padded.ptr, 0x00, padded.len - 1);
- if (pos)
- {
- pos++;
- *plain = chunk_clone(chunk_create(
- pos, padded.len - (pos - padded.ptr)));
- }
- }
+
+ decrypted.ptr = (u_char*)gcry_sexp_nth_data(out, 1, &decrypted.len);
+ *plain = chunk_clone(decrypted);
gcry_sexp_release(out);
- if (!pos)
- {
- DBG1(DBG_LIB, "decrypted data has invalid pkcs1 padding");
- return FALSE;
- }
+
return TRUE;
}
private_gcrypt_rsa_public_key_t *this, encryption_scheme_t scheme,
void *params, chunk_t plain, chunk_t *encrypted)
{
- gcry_sexp_t in, out;
gcry_error_t err;
+ gcry_sexp_t in, out;
+ chunk_t label = chunk_empty;
+ u_char *sexp;
- if (scheme != ENCRYPT_RSA_PKCS1)
+ switch (scheme)
{
- DBG1(DBG_LIB, "encryption scheme %N not supported",
- encryption_scheme_names, scheme);
- return FALSE;
+ case ENCRYPT_RSA_PKCS1:
+ sexp = "(data(flags pkcs1)(value %b))";
+ break;
+ case ENCRYPT_RSA_OAEP_SHA1:
+ sexp = "(data(flags oaep)(value %b))";
+ break;
+ default:
+ DBG1(DBG_LIB, "encryption scheme %N not supported",
+ encryption_scheme_names, scheme);
+ return FALSE;
}
- /* "pkcs1" uses PKCS 1.5 (section 8.1) block type 2 encryption:
- * 00 | 02 | RANDOM | 00 | DATA */
- err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(value %b))",
- plain.len, plain.ptr);
+
+ if (scheme == ENCRYPT_RSA_OAEP_SHA1 && params != NULL)
+ {
+ label = *(chunk_t *)params;
+ if (label.len > 0)
+ {
+ DBG1(DBG_LIB, "RSA OAEP encryption with a label not supported");
+ return FALSE;
+ }
+ }
+
+ err = gcry_sexp_build(&in, NULL, sexp, plain.len, plain.ptr);
if (err)
{
DBG1(DBG_LIB, "building encryption S-expression failed: %s",
gpg_strerror(err));
return FALSE;
}
+
err = gcry_pk_encrypt(&out, in, this->key);
gcry_sexp_release(in);
if (err)
{
- DBG1(DBG_LIB, "encrypting data using pkcs1 failed: %s",
- gpg_strerror(err));
+ DBG1(DBG_LIB, "RSA encryption failed: %s", gpg_strerror(err));
return FALSE;
}
+
*encrypted = gcrypt_rsa_find_token(out, "a", this->key);
gcry_sexp_release(out);
- return !!encrypted->len;
+
+ return encrypted->len > 0;
}
METHOD(public_key_t, get_keysize, int,