-
Notifications
You must be signed in to change notification settings - Fork 4
Hmac support #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hmac support #27
Conversation
Support for protected HMAC keys comes with MSA 11. Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
rc = ZPC_ERROR_PVSECRET_ID_NOT_FOUND_IN_UV; | ||
goto ret; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it checked anywhere that the retrievable secret type is the expected HMAC type? There is ZPC_HMAC_SECRET_HMAC_SHA_256 or ZPC_HMAC_SECRET_HMAC_SHA_512, and the to be imported key must match the keysize set in the key object.
Also the hash type set via zpc_hmac_key_set_hash_function() must match to the secret type. Inconsistencies should be rejected (i.e. you can't use hash function SHA-512 with a retrievable secret of type ZPC_HMAC_SECRET_HMAC_SHA_256).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the logic is like:
- setting the hash function for a key obj causes the key size to be set accordingly: 512 or 1024. There is no separate "set_size" function.
- importing a secret ID only checks if the pvsecret is available in the system.
- But when using the key later in the hmac context, the CPACF function code is set depending on the hash function of the key (see local routine __hmac_init in hmac.c). I.e. the hash function is not a property of the context, but only of the key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but what if one set SHA-256 as a hash function, but the secret ID points to a secret of type HMAC_SHA_512. This won't work together. I don't see any checks for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per our offline discussions on this, I added commit "Make rc more informative".
case ZPC_HMAC_HASHFUNC_SHA_256: | ||
case ZPC_HMAC_HASHFUNC_SHA_384: | ||
case ZPC_HMAC_HASHFUNC_SHA_512: | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it checked anywhere that the hash function set here matches the retrievable secret type (ZPC_HMAC_SECRET_HMAC_SHA_xxx) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As commented above, the retrievable secret type is derived from the hash function. The import function checks if the expected secret is available in the system. For this check, the expected secret type is set in the ioctl, see routine hmac_key_make_uvrsecrettoken() in hmac_key.c.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so if the secret ID as such is valid and exists, but the type does not match the expended type, then it fails.
Does it produce different error codes if
1.) the secret Id does not exist at all
2.) the secret Id exists, but is a wrong type ?
This would be important to differentiate to give the user a hit about whats wrong.
(did not look into the code, sorry)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, good point. At the moment the PKEY_VERIFYKEY2 ioctl just fails if the "expected" secret is not available. But I'm not checking if the given secret ID probably points to an existing secret with another type. Maybe I could change the check so that both types are tried. Then we would see the exact error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline I added another commit to make the rc ZPC_ERROR_PVSECRET_ID_NOT_FOUND_IN_UV more informative.
c73dff0
to
fad91b0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A mentioned in the comments, I would prefer to get rid of the assert() calls.
Please also fix the version number.
The rest looks good so far.
@@ -95,4 +95,15 @@ global: | |||
local: *; | |||
} ZPC_1.1.0; | |||
|
|||
ZPC_1.4.0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we skip 1.3.0? If this related to other features, I would recommend to do the PRs in the right sequence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1.3.0 (and even 1.3.1) is already upstream. This was the fips 140-3 update in 2024 and caused the API behavior to change, but there were no new API functions. Therefore we go to 1.4.0 now.
} | ||
attr_init = 1; | ||
rv = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | ||
assert(rv == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, that the existing code uses assert()
calls a lot. IMO this is not the right way of error checking in libraries. I would prefer error return values instead of assert()
for any new library-code.
Just to be mentioned: using assert()
in the test-cases is absolutely fine!
(this applies to all asserts in ./src/*.c)
Per our offline discussion on this I'm leaving the assert calls for now. This will be a major restructuring and should be done in a separate item. |
The following variants of protected HMAC keys are supported: - created from Ultravisor (UV) retrievable secrets (pvsecrets). - created from given clear key data (via PKEY_KBLOB2PROTK3 ioctl). - generated via sysfs attributes protkey_hmac_512 and protkey_hmac_1024 in /sys/devices/virtual/misc/pkey/protkey. Each new read on one of these sysfs attributes provides a new key of the related type. Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
In the same way as for the libzpc CMAC API, if the mac parm is NULL, then an intermediate signing op is performed. If the mac parm is not NULL and the maclen is a valid MAC length, then the final MAC is computed. For verify, if the mac parm is NULL, then an intermediate verify op is performed. If the mac parm is not NULL and the maclen is a valid MAC length, then the given MAC is checked for correctness. Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Provide additional test functionality for protected-key HMAC testing. Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Mainly remove duplicate code and change some int's to size_t. While at it, also make parsing of pvsecret list file a bit more flexible. Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Tests for protected-key HMAC cover protected keys retrieved from Ultravisor retrievable secrets, random HMAC keys, and HMAC keys created from given clear key data. Tests with random HMAC keys and HMAC keys created from clear key data can be performed on a z17 or later. Ultravisor retrievable secrets are only supported on z17 or later in a secure execution guest under KVM. Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
Searching for a given secret ID always means searching for an ID of a given secret type (AES-128-KEY, AES-192-KEY, HMAC-SHA-256-KEY, etc.). If this fails, there are two possible reasons: there is no secret with the given ID in the system, or the given ID belongs to a secret with another type. Therefore make the related rc and its description more informative. Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
ok with me. |
This pull request adds support for MSA 11 protected key HMAC support to libzpc.