From e800af8e1aee2336baa8b654c239f8a12df74cd5 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 13 May 2016 19:16:25 +0200 Subject: [PATCH] get/set_ctx_param for sign/verify (RSA padding only) Change-Id: I9ce5bde7a43bae619546c9cc5b3e54c4388ca755 --- api/yaca/types.h | 11 +++-- examples/sign.c | 11 +---- src/sign.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 16 deletions(-) diff --git a/api/yaca/types.h b/api/yaca/types.h index 7ce9ec9..72d45f4 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -310,12 +310,11 @@ typedef enum { */ 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; /**@}*/ diff --git a/examples/sign.c b/examples/sign.c index 4874131..faf0131 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -30,8 +30,6 @@ #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) { @@ -41,9 +39,7 @@ 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) @@ -56,11 +52,8 @@ void sign_verify_asym(yaca_key_type_e type, const char *algo) 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; @@ -84,10 +77,8 @@ void sign_verify_asym(yaca_key_type_e type, const char *algo) 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; diff --git a/src/sign.c b/src/sign.c index 3ad2279..9573c4c 100644 --- a/src/sign.c +++ b/src/sign.c @@ -17,8 +17,10 @@ */ #include +#include #include +#include #include #include @@ -95,6 +97,129 @@ static void destroy_sign_context(yaca_ctx_h ctx) 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); @@ -157,6 +282,8 @@ API int yaca_sign_init(yaca_ctx_h *ctx, 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) { @@ -274,6 +401,8 @@ API int yaca_verify_init(yaca_ctx_h *ctx, 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) { -- 2.7.4