*/
typedef enum {
YACA_PADDING_NONE = 0, /**< total number of data MUST multiple of block size, Default */
- YACA_PADDING_ZEROS, /**< pad with zeros */
- YACA_PADDING_ISO10126, /**< ISO 10126 */
- YACA_PADDING_ANSIX923, /**< ANSI X.923 padding*/
- YACA_PADDING_ANSIX931, /**< ANSI X.931 padding*/
- YACA_PADDING_PKCS1, /**< RSA signature creation */
- YACA_PADDING_PKCS7 /**< Byte padding for symetric algos (RFC 5652), (PKCS5 padding is the same) */
+ YACA_PADDING_X931, /**< RSA X9.31 padding*/
+ YACA_PADDING_PKCS1, /**< RSA signature/verify operations */
+ YACA_PADDING_PKCS1_PSS, /**< RSA signature/verify operations */
+ YACA_PADDING_SSLV23, /**< RSA SSLv23 */
+ YACA_PADDING_PKCS1_OAEP /**< RSA encrypt/decrypt operations */
} yaca_padding_e;
/**@}*/
#include "lorem.h"
#include "misc.h"
-#define PADDING_IMPLEMENTED 0
-
// Signature creation and verification using advanced API
void sign_verify_asym(yaca_key_type_e type, const char *algo)
{
yaca_ctx_h ctx = YACA_CTX_NULL;
yaca_key_h prv = YACA_KEY_NULL;
yaca_key_h pub = YACA_KEY_NULL;
-#if PADDING_IMPLEMENTED
- yaca_padding_e padding = YACA_PADDING_PKCS1;
-#endif
+ yaca_padding_e padding = YACA_PADDING_PKCS1_PSS;
// GENERATE
if (yaca_key_gen(&prv, type, YACA_KEY_1024BIT) != 0)
if (yaca_sign_init(&ctx, YACA_DIGEST_SHA512, prv) != 0)
goto finish;
-#if PADDING_IMPLEMENTED
- // TODO: yaca_ctx_set_param should take void* not char*
if (yaca_ctx_set_param(ctx, YACA_PARAM_PADDING, (char*)(&padding), sizeof(padding)) != 0)
goto finish;
-#endif
if (yaca_sign_update(ctx, lorem4096, LOREM4096_SIZE) != 0)
goto finish;
if (yaca_verify_init(&ctx, YACA_DIGEST_SHA512, pub) != 0)
goto finish;
-#if PADDING_IMPLEMENTED
if (yaca_ctx_set_param(ctx, YACA_PARAM_PADDING, (char*)(&padding), sizeof(padding)) != 0)
goto finish;
-#endif
if (yaca_verify_update(ctx, lorem4096, LOREM4096_SIZE) != 0)
goto finish;
*/
#include <assert.h>
+#include <string.h>
#include <openssl/evp.h>
+#include <openssl/rsa.h>
#include <yaca/crypto.h>
#include <yaca/error.h>
c->mdctx = NULL;
}
+int set_sign_param(yaca_ctx_h ctx, yaca_ex_param_e param, const void *value, size_t value_len)
+{
+ int ret;
+ struct yaca_sign_ctx_s *c = get_sign_ctx(ctx);
+ yaca_padding_e padding;
+ int pad;
+ EVP_PKEY *pkey;
+
+ if (c == NULL || value == NULL)
+ return YACA_ERROR_INVALID_ARGUMENT;
+
+ assert(c->mdctx != NULL);
+
+ if (c->mdctx->pctx == NULL)
+ return YACA_ERROR_INTERNAL;
+
+ /* this function only supports padding */
+ if (param != YACA_PARAM_PADDING || value_len != sizeof(yaca_padding_e))
+ return YACA_ERROR_INVALID_ARGUMENT;
+
+ padding = *(yaca_padding_e *)(value);
+
+ // TODO: investigate whether it's possible to set
+ // RSA_NO_PADDING or RSA_SSLV23_PADDING in some cases
+ switch (padding) {
+ case YACA_PADDING_X931:
+ pad = RSA_X931_PADDING;
+ break;
+ case YACA_PADDING_PKCS1:
+ pad = RSA_PKCS1_PADDING;
+ break;
+ case YACA_PADDING_PKCS1_PSS:
+ pad = RSA_PKCS1_PSS_PADDING;
+ break;
+ default:
+ return YACA_ERROR_INVALID_ARGUMENT;
+ }
+
+ pkey = EVP_PKEY_CTX_get0_pkey(c->mdctx->pctx);
+ if (pkey == NULL) {
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(ret);
+ return ret;
+ }
+
+ /* padding only works for RSA */
+ if (pkey->type != EVP_PKEY_RSA)
+ return YACA_ERROR_INVALID_ARGUMENT;
+
+ ret = EVP_PKEY_CTX_set_rsa_padding(c->mdctx->pctx, pad);
+ if (ret <= 0) {
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int get_sign_param(const yaca_ctx_h ctx, yaca_ex_param_e param, void **value, size_t *value_len)
+{
+ int ret;
+ struct yaca_sign_ctx_s *c = get_sign_ctx(ctx);
+ EVP_PKEY *pkey;
+ int pad;
+ yaca_padding_e padding;
+
+ if (c == NULL || value == NULL || value_len == NULL)
+ return YACA_ERROR_INVALID_ARGUMENT;
+
+ assert(c->mdctx != NULL);
+
+ if (c->mdctx->pctx == NULL)
+ return YACA_ERROR_INTERNAL;
+
+ /* this function only supports padding */
+ if (param != YACA_PARAM_PADDING)
+ return YACA_ERROR_INVALID_ARGUMENT;
+
+ pkey = EVP_PKEY_CTX_get0_pkey(c->mdctx->pctx);
+ if (pkey == NULL) {
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(ret);
+ return ret;
+ }
+
+ /* padding only works for RSA */
+ if (pkey->type != EVP_PKEY_RSA)
+ return YACA_ERROR_INVALID_ARGUMENT;
+
+ ret = EVP_PKEY_CTX_get_rsa_padding(c->mdctx->pctx, &pad);
+ if (ret <= 0) {
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(ret);
+ return ret;
+ }
+
+ switch(pad) {
+ case RSA_X931_PADDING:
+ padding = YACA_PADDING_X931;
+ break;
+ case RSA_PKCS1_PADDING:
+ padding = YACA_PADDING_PKCS1;
+ break;
+ case RSA_PKCS1_PSS_PADDING:
+ padding = YACA_PADDING_PKCS1_PSS;
+ break;
+ default:
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(YACA_ERROR_INTERNAL);
+ return ret;
+ }
+
+ *value = yaca_malloc(sizeof(yaca_padding_e));
+ if (*value == NULL)
+ return YACA_ERROR_OUT_OF_MEMORY;
+
+ memcpy(*value, &padding, sizeof(yaca_padding_e));
+ *value_len = sizeof(yaca_padding_e);
+
+ return 0;
+}
+
static int create_sign_pkey(const yaca_key_h key, EVP_PKEY **pkey)
{
const struct yaca_key_simple_s *simple_key = key_get_simple(key);
nc->ctx.type = YACA_CTX_SIGN;
nc->ctx.ctx_destroy = destroy_sign_context;
nc->ctx.get_output_length = get_sign_output_length;
+ nc->ctx.set_param = set_sign_param;
+ nc->ctx.get_param = get_sign_param;
switch (key->type)
{
nc->ctx.type = YACA_CTX_SIGN;
nc->ctx.ctx_destroy = destroy_sign_context;
nc->ctx.get_output_length = NULL;
+ nc->ctx.set_param = set_sign_param;
+ nc->ctx.get_param = get_sign_param;
switch (key->type)
{