Skip to content

Comments

Add SM2 key management#12536

Closed
InfoHunter wants to merge 13 commits intoopenssl:masterfrom
InfoHunter:sm2-keymgmt
Closed

Add SM2 key management#12536
InfoHunter wants to merge 13 commits intoopenssl:masterfrom
InfoHunter:sm2-keymgmt

Conversation

@InfoHunter
Copy link
Member

@InfoHunter InfoHunter commented Jul 26, 2020

Add support for SM2 key management in provider. This is mainly based on #11248 (comment)

Checklist
  • documentation is added or updated
  • tests are added or updated

@InfoHunter
Copy link
Member Author

Note: it's only a skeleton at current stage and I will add real content later ;-)

@InfoHunter
Copy link
Member Author

I added the SM2 key generation by specifying a new EC flag into the EC_KEY object and thus the ec_generate_key function can behave correctly for an SM2 private key. Any ideas? @openssl/committers

@levitte
Copy link
Member

levitte commented Jul 27, 2020

I added the SM2 key generation by specifying a new EC flag into the EC_KEY object and thus the ec_generate_key function can behave correctly for an SM2 private key. Any ideas? @openssl/committers

I had the same idea. Considering how little they differ otherwise, I think this is the sane way to do it.

@InfoHunter InfoHunter changed the title WIP: Add SM2 key management Add SM2 key management Aug 1, 2020
@InfoHunter InfoHunter requested a review from levitte August 1, 2020 16:53
@InfoHunter
Copy link
Member Author

WIP has just been removed. Please have a review on this @openssl/committers , thanks!

Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work without the equivalent exchange/signature implementations? Or does it fallback to legacy somehow???

Are our current tests actually hitting these codepaths? From code inspection it looks to me like ec_generate_key will crash in the SM2 codepath - which makes we wonder whether we ever actually get there....or am I wrong about the crash?

@InfoHunter
Copy link
Member Author

How does this work without the equivalent exchange/signature implementations? Or does it fallback to legacy somehow???

Actually this PR should base on PR #11248 , so it will fail from my understandings.

@InfoHunter
Copy link
Member Author

Are our current tests actually hitting these codepaths?

Anything I need to do to include this in to our tests?

@levitte
Copy link
Member

levitte commented Aug 7, 2020

For testing, I would remove these lines and see what happens:

#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_EC)
# define TMP_SM2_HACK
#endif

@InfoHunter
Copy link
Member Author

After I tried to remove the macro @levitte suggested, it seems no changes on the testing side. But I investigate a bit on other test case failure and fixed the test_ecdsa.t to match the new changes introduced in this PR.

@InfoHunter
Copy link
Member Author

I noticed one test failure on EVP_PKEY_CTX_set1_id. From my understanding, this should not fail on introducing new SM2 keymgmt code since the ID is located in SM2 pkey ctx. Could you please have a look on this if you have spare time @levitte ?

@levitte
Copy link
Member

levitte commented Aug 9, 2020

I noticed one test failure on EVP_PKEY_CTX_set1_id. From my understanding, this should not fail on introducing new SM2 keymgmt code since the ID is located in SM2 pkey ctx. Could you please have a look on this if you have spare time @levitte ?

Well, it works with the legacy SM2 implementation, because this:

case EVP_PKEY_CTRL_SET1_ID:
if (p1 > 0) {
tmp_id = OPENSSL_malloc(p1);
if (tmp_id == NULL) {
SM2err(SM2_F_PKEY_SM2_CTRL, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(tmp_id, p2, p1);
OPENSSL_free(smctx->id);
smctx->id = tmp_id;
} else {
/* set null-ID */
OPENSSL_free(smctx->id);
smctx->id = NULL;
}
smctx->id_len = (size_t)p1;
smctx->id_set = 1;
return 1;
case EVP_PKEY_CTRL_GET1_ID:
memcpy(p2, smctx->id, smctx->id_len);
return 1;

and this:

} else if (strcmp(type, "distid") == 0) {
return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID,
(int)strlen(value), (void *)value);
} else if (strcmp(type, "hexdistid") == 0) {
hex_id = OPENSSL_hexstr2buf((const char *)value, &hex_len);
if (hex_id == NULL) {
SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
ret = pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, (int)hex_len,
(void *)hex_id);
OPENSSL_free(hex_id);
return ret;
}

What you need to do is to convert that macro to something that handles OSSL_PARAM, and you need to be able to handle that in the SM2 signature implementation. You can have a look at what we already do for EC for inspiration (the reason I point at UKM stuff is the use of octet_string, which is what I recommend for the ID):

openssl/crypto/ec/ec_ctrl.c

Lines 351 to 422 in 04cb5ec

int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
{
int ret;
OSSL_PARAM params[2], *p = params;
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
if (ret != 1)
return ret;
/* TODO(3.0): Remove this eventually when no more legacy */
if (ctx->op.kex.exchprovctx == NULL)
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_UKM, len, (void *)(ukm));
*p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
/*
* Cast away the const. This is read
* only so should be safe
*/
(void *)ukm,
(size_t)len);
*p++ = OSSL_PARAM_construct_end();
ret = evp_pkey_ctx_set_params_strict(ctx, params);
if (ret == -2) {
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
return -2;
}
if (ret == 1)
OPENSSL_free(ukm);
return ret;
}
int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
{
size_t ukmlen;
int ret;
OSSL_PARAM params[3], *p = params;
ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
if (ret != 1)
return ret;
/* TODO(3.0): Remove this eventually when no more legacy */
if (ctx->op.kex.exchprovctx == NULL)
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0,
(void *)(pukm));
*p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
(void **)pukm, 0);
*p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN,
&ukmlen);
*p++ = OSSL_PARAM_construct_end();
ret = evp_pkey_ctx_get_params_strict(ctx, params);
if (ret == -2) {
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
return -2;
} else if (ret != 1) {
return -1;
}
if (ukmlen > INT_MAX)
return -1;
return (int)ukmlen;
}

Other places to touch are:

(to "translate" EVP_PKEY_CTRL_SET1_ID and EVP_PKEY_CTRL_GET1_ID to the new functions)

static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,

(to "translate" 'distid' to whatever OSSL_PARAM name you come up with)

static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,

@levitte
Copy link
Member

levitte commented Aug 9, 2020

(.. and now backing away to do more vacation ..)

@InfoHunter
Copy link
Member Author

I pulled the commits from #11248 into this PR thus we have the signature implementation. So can we close #11248 and review the whole change together in this PR? (This would be more convenient)

@mattcaswell
Copy link
Member

Makes sense to me

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

@InfoHunter
Copy link
Member Author

Needs a rebase.

Done rebasing.

@mattcaswell
Copy link
Member

Was the rebase trivial? If so then I don't see a need to reset the 24hr timer.

@InfoHunter
Copy link
Member Author

Was the rebase trivial? If so then I don't see a need to reset the 24hr timer.

Yes, only 2 build.info files

@levitte
Copy link
Member

levitte commented Sep 22, 2020

To my judgement, there's no need to delay a merge further.

openssl-machine pushed a commit that referenced this pull request Sep 22, 2020
Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
(Merged from #12536)
openssl-machine pushed a commit that referenced this pull request Sep 22, 2020
Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
(Merged from #12536)
openssl-machine pushed a commit that referenced this pull request Sep 22, 2020
Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
(Merged from #12536)
openssl-machine pushed a commit that referenced this pull request Sep 22, 2020
Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
(Merged from #12536)
openssl-machine pushed a commit that referenced this pull request Sep 22, 2020
Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
(Merged from #12536)
openssl-machine pushed a commit that referenced this pull request Sep 22, 2020
Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
(Merged from #12536)
@mattcaswell
Copy link
Member

Repo is frozen due to the release today - but this is master only so I pushed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: done This pull request has the required number of approvals branch: master Applies to master branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants