diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-04-13 20:16:56 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-04-13 20:16:56 +0000 |
commit | ffb1ac674c8294bf519add26fb37d94b7afeceb4 (patch) | |
tree | 5348fcd74b5757bd76b6cee7e81d3fe2717a5e9e /crypto/evp | |
parent | 3be34589e8d7d164221d393844e8a841dce992a9 (diff) |
Complete key derivation support.
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/evp.h | 8 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 3 | ||||
-rw-r--r-- | crypto/evp/pmeth_fn.c | 60 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 2 |
4 files changed, 73 insertions, 0 deletions
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index d60781696a..bfffdd562a 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -933,6 +933,7 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, EVP_PKEY_CTRL_MD, 0, (void *)md) #define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_PEER_KEY 2 #define EVP_PKEY_ALG_CTRL 0x1000 @@ -972,6 +973,10 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen, const unsigned char *in, int inlen); +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, int *keylen); + typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); @@ -1018,6 +1023,7 @@ void ERR_load_EVP_strings(void); #define EVP_F_EVP_PKEY_DECRYPT_OLD 151 #define EVP_F_EVP_PKEY_DERIVE 153 #define EVP_F_EVP_PKEY_DERIVE_INIT 154 +#define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 #define EVP_F_EVP_PKEY_ENCRYPT 105 #define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 #define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 @@ -1061,6 +1067,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 #define EVP_R_DECODE_ERROR 114 #define EVP_R_DIFFERENT_KEY_TYPES 101 +#define EVP_R_DIFFERENT_PARAMETERS 153 #define EVP_R_ENCODE_ERROR 115 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 #define EVP_R_EXPECTING_AN_RSA_KEY 127 @@ -1080,6 +1087,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_NO_CIPHER_SET 131 #define EVP_R_NO_DIGEST_SET 139 #define EVP_R_NO_DSA_PARAMETERS 116 +#define EVP_R_NO_KEY_SET 154 #define EVP_R_NO_OPERATION_SET 149 #define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 50d5a71276..225564d25e 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -97,6 +97,7 @@ static ERR_STRING_DATA EVP_str_functs[]= {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"}, {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_DERIVE"}, {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_DERIVE_INIT"}, +{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_DERIVE_SET_PEER"}, {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"}, {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"}, {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"}, @@ -143,6 +144,7 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"}, {ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"}, +{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) ,"different parameters"}, {ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"}, {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"}, {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"}, @@ -162,6 +164,7 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"}, {ERR_REASON(EVP_R_NO_DIGEST_SET) ,"no digest set"}, {ERR_REASON(EVP_R_NO_DSA_PARAMETERS) ,"no dsa parameters"}, +{ERR_REASON(EVP_R_NO_KEY_SET) ,"no key set"}, {ERR_REASON(EVP_R_NO_OPERATION_SET) ,"no operation set"}, {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"}, {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"}, diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c index 0ad8098718..3d09ba245a 100644 --- a/crypto/evp/pmeth_fn.c +++ b/crypto/evp/pmeth_fn.c @@ -262,6 +262,66 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) return ret; } +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) + { + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive || !ctx->pmeth->ctrl) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) + return ret; + + if (ret == 2) + return 1; + + if (!ctx->pkey) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); + return -1; + } + + if (ctx->pkey->type != peer->type) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_DIFFERENT_KEY_TYPES); + return -1; + } + + if (!EVP_PKEY_missing_parameters(peer) && + !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) + { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_DIFFERENT_PARAMETERS); + return -1; + } + + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) + { + ctx->peerkey = NULL; + return ret; + } + + CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY); + return 1; + } + + int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, int *pkeylen) { if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 95b1e4ed3c..97fcf26012 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -153,6 +153,8 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) ctx->pmeth->cleanup(ctx); if (ctx->pkey) EVP_PKEY_free(ctx->pkey); + if (ctx->peerkey) + EVP_PKEY_free(ctx->peerkey); OPENSSL_free(ctx); } |