And then there was enlightenment. Sometimes looking at the documentation a 
hundred times is not enough ; it's the 101st which pays off.

I got the signature to work. Here's a minimal example:

  /* key generation */

  EVP_PKEY_CTX* keygen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
  EVP_PKEY* pkey = NULL;

  if (EVP_PKEY_keygen_init(keygen_ctx)<1) OSSL_err();
  if (EVP_PKEY_CTX_set_rsa_keygen_bits(keygen_ctx, 2048)<1) OSSL_err();

  if (EVP_PKEY_keygen(keygen_ctx, &pkey)<1) OSSL_err();

  /* signing */

  EVP_MD_CTX* md_ctx = EVP_MD_CTX_create();

  if (EVP_DigestSignInit(md_ctx, &keygen_ctx, EVP_sha256(), NULL, pkey)<1)
    OSSL_err();

  if (EVP_PKEY_CTX_set_rsa_padding(keygen_ctx, RSA_PKCS1_PSS_PADDING)<1)
    OSSL_err();
  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(keygen_ctx, -2)<1)
    OSSL_err();

  char* message = "Welcome to die!";
  unsigned int message_l = strlen(message);

  unsigned int signature_l = EVP_PKEY_size(pkey);
  unsigned char signature[signature_l];

  if (EVP_DigestSignUpdate(md_ctx, message, message_l)<1) OSSL_err();

  if (EVP_DigestSignFinal(md_ctx, signature, &signature_l)<1) OSSL_err();
  
  /* verifying */

  EVP_MD_CTX* verif_ctx = EVP_MD_CTX_create();

  if (EVP_DigestVerifyInit(verif_ctx, &keygen_ctx, EVP_sha256(), NULL, pkey)<1)
    OSSL_err();

  if (EVP_PKEY_CTX_set_rsa_padding(verif_ctx->pctx, RSA_PKCS1_PSS_PADDING)<1)
    OSSL_err();
  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(verif_ctx->pctx, -2)<1)
    OSSL_err();

  if (EVP_DigestVerifyUpdate(verif_ctx, message, message_l)<1)
    OSSL_err();

  int res = EVP_DigestVerifyFinal(verif_ctx, signature, signature_l);
  switch(res) {
  case 1:printf("sig checks out!\n"); break;
  case 0:printf("nope nope nope.\n"); break;
  default: OSSL_err();
  }
  
This also works if I call EVP_Digest*Init with NULL as the second argument, and 
then use the EVP_PKEY_CTX_set* functions on md_ctx->pctx before calling 
EVP_Digest*Update. But this is, I suppose, not the intended way to do it.

If I understand correctly, my mistake was assuming that a EVP_PKEY_CTX is a 
structure used only for key generation, rather than an all-purpose public key 
structure used for all operations.

Sorry for spamming the list!





----- Original Message -----
From: "Kevin Le Gouguec" <[email protected]>
To: [email protected]
Sent: Tuesday, March 4, 2014 12:16:21 PM
Subject: [1.0.1f] RSA-PSS signing through EVP interface

Hello,

I'm having a hard time figuring out how to use the EVP interface to get a 
RSA-PSS signature. I can successfully call RSA_padding_add_PKCS1_PSS, but when 
I try to call the various macros for EVP_PKEY_CTX_ctrl.

The thing is, I'm not sure in which order (if any) these functions should be 
called. Currently, this is what I have: (OSSL_err() calls 
ERR_print_errors_fp(stderr))

  EVP_PKEY_CTX* keygen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
  EVP_PKEY* pkey = NULL;

  if (EVP_PKEY_keygen_init(keygen_ctx)<1) OSSL_err();
  else printf("keygen init ok\n");

  if (EVP_PKEY_CTX_set_rsa_keygen_bits(keygen_ctx, 2048)<1) OSSL_err();
  else printf("set rsa keygen bits ok\n");

  if (EVP_PKEY_CTX_set_rsa_padding(keygen_ctx, RSA_PKCS1_PSS_PADDING)<1) 
OSSL_err();
  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(keygen_ctx, -2)<1) OSSL_err();

  if (EVP_PKEY_keygen(keygen_ctx, &pkey)<1) OSSL_err(); else printf("keygen 
ok\n");


When I call the functions in this order, I get everything okay up to 
set_rsa_padding, which returns 
0:error:0408F090:rsa routines:PKEY_RSA_CTRL:illegal or unsupported padding 
mode:rsa_pmeth.c:403:
0:error:06089093:digital envelope routines:EVP_PKEY_CTX_ctrl:command not 
supported:pmeth_lib.c:358:

If I call set_rsa_pss_salten before set_rsa_padding, I get
0:error:06089094:digital envelope routines:EVP_PKEY_CTX_ctrl:invalid 
operation:pmeth_lib.c:351:

EVP_PKEY_keygen works if I call it before those two. I also tried to use 
EVP_PKEY_CTX_set_signature_md before them, to no avail.

Is there anything obvious I'm missing? I tried building the library and 
enabling debug mode, but I can't get gdb to find the source. Simply browsing 
the code got me nowhere.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [email protected]
Automated List Manager                           [email protected]
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [email protected]
Automated List Manager                           [email protected]

Reply via email to