Message ID | 20180228165230.18729-2-tudor.ambarus@microchip.com (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | Herbert Xu |
Headers | show |
Hi Tudor, On 02/28/2018 10:52 AM, Tudor Ambarus wrote: > Provide three new operations in the key_type struct that can be used to > provide access to kpp operations. These will be implemented for the > asymmetric key type in a later patch and may refer to a key retained in > RAM by the kernel or a key retained in crypto hardware. > > int (*asym_kpp_query)(const struct kernel_kpp_params *params, > struct kernel_kpp_query *res); > int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, > void *out); > int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, > const void *in, void *out); > > Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> > --- > Documentation/security/keys/core.rst | 54 ++++++++++++++++++++++++++++++++++++ > include/linux/key-type.h | 7 +++++ > include/linux/keyctl.h | 11 ++++++++ > include/uapi/linux/keyctl.h | 3 ++ > 4 files changed, 75 insertions(+) > > diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst > index d224fd0..9b69a1f 100644 > --- a/Documentation/security/keys/core.rst > +++ b/Documentation/security/keys/core.rst > @@ -1688,6 +1688,60 @@ The structure has a number of fields, some of which are mandatory: > If successful, 0 will be returned. If the key doesn't support this, > EOPNOTSUPP will be returned. > > + * ``int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void *out);`` > + * ``int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, const void *in, void *out);`` > + > + These methods are optional. If provided the first allows to generate the > + public key pair corresponding to the private key. The second method allows > + to generate a shared secret by combining the private key and the other > + party's public key. > + > + In all cases, the following information is provided in the params block:: > + > + struct kernel_kpp_query { > + struct key *key; > + __u32 in_len; /* Input data size */ > + __u32 out_len; /* Output buffer size */ > + } > + Probably not a huge deal as most common key sizes are already supported, but... is there a way to query supported key sizes? I think for DH_COMPUTE we didn't have this problem as everything was done in software. However, if the intent is to use TPM / other hardware engines we might need a way to query supported key sizes. > + This includes the key to be used and the sizes in bytes of the input and > + output buffers. > + > + For a given operation, the in and out buffers are used as follows:: > + > + Operation ID in,in_len out,out_len > + ======================= =================== ======================== > + KEYCTL_KPP_GEN_PUBKEY - Corresponding public key > + KEYCTL_KPP_COMPUTE_SS Pair's public key Shared Secret > + > + If successful, the public key generation and the shared secret computation > + will return the amount of data written into the output buffer. > + > + * ``int (*asym_kpp_query)(const struct kernel_kpp_params *params, struct kernel_kpp_query *res);`` > + > + This method is optional. If provided it allows information about the > + asymmetric KPP (Key Protocol Primitives) key held in the key to be > + determined. > + > + The ``params`` block will contain the key to be queried. ``in_len`` and > + ``out_len`` are unused. > + > + If successful, the following information is filled in:: > + > + struct kernel_kpp_query { > + __u32 supported_ops; /* Which ops are supported */ > + __u32 max_size; /* Maximum size of the output buffer */ > + }; > + > + The supported_ops field will contain a bitmask indicating what operations > + are supported by the key, including public key generation and shared > + secret computation. The following constants are defined for this:: > + > + KEYCTL_SUPPORTS_{GEN_PUBKEY, COMPUTE_SS}; > + > + If successful, 0 is returned. If the key is not an asymmetric kpp key, > + EOPNOTSUPP is returned. > + > > Request-Key Callback Service > ============================ > diff --git a/include/linux/key-type.h b/include/linux/key-type.h > index bc9af55..d354b6b 100644 > --- a/include/linux/key-type.h > +++ b/include/linux/key-type.h > @@ -19,6 +19,8 @@ > > struct kernel_pkey_query; > struct kernel_pkey_params; > +struct kernel_kpp_query; > +struct kernel_kpp_params; > > /* > * key under-construction record > @@ -165,6 +167,11 @@ struct key_type { > const void *in, void *out); > int (*asym_verify_signature)(struct kernel_pkey_params *params, > const void *in, const void *in2); > + int (*asym_kpp_query)(const struct kernel_kpp_params *params, > + struct kernel_kpp_query *res); > + int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void *out); > + int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, > + const void *in, void *out); > > /* internal fields */ > struct list_head link; /* link in types list */ > diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h > index e89b4a4..8f464ea 100644 > --- a/include/linux/keyctl.h > +++ b/include/linux/keyctl.h > @@ -43,4 +43,15 @@ struct kernel_pkey_params { > enum kernel_pkey_operation op : 8; > }; > > +struct kernel_kpp_query { > + __u32 supported_ops; /* Which ops are supported */ > + __u32 max_size; /* Maximum size of the output buffer */ > +}; > + > +struct kernel_kpp_params { > + struct key *key; > + __u32 in_len; /* Input data size */ > + __u32 out_len; /* Output buffer size */ > +}; > + > #endif /* __LINUX_KEYCTL_H */ > diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h > index d75d208..98b79f8 100644 > --- a/include/uapi/linux/keyctl.h > +++ b/include/uapi/linux/keyctl.h > @@ -107,4 +107,7 @@ struct keyctl_pkey_params { > __u32 __spare[7]; > }; > > +#define KEYCTL_SUPPORTS_GEN_PUBKEY 0x0f This looks fishy, the other KEYCTL_SUPPORTS_ block ends at 0x08. This would imply that KPP supports encryption, decryption, sign, verify. Do you mean 0x10 here? > +#define KEYCTL_SUPPORTS_COMPUTE_SS 0x10 > + And 0x20 here? > #endif /* _LINUX_KEYCTL_H */ > Otherwise this looks good to me. Feel free to add: Reviewed-by: Denis Kenzior <denkenz@gmail.com> Regards, -Denis
Hi, Denis, Thanks for the review! Please see inline. On 05/14/2018 09:48 PM, Denis Kenzior wrote: > Hi Tudor, > > On 02/28/2018 10:52 AM, Tudor Ambarus wrote: >> Provide three new operations in the key_type struct that can be used to >> provide access to kpp operations. These will be implemented for the >> asymmetric key type in a later patch and may refer to a key retained in >> RAM by the kernel or a key retained in crypto hardware. >> >> int (*asym_kpp_query)(const struct kernel_kpp_params *params, >> struct kernel_kpp_query *res); >> int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, >> void *out); >> int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, >> const void *in, void *out); >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> >> --- >> Documentation/security/keys/core.rst | 54 >> ++++++++++++++++++++++++++++++++++++ >> include/linux/key-type.h | 7 +++++ >> include/linux/keyctl.h | 11 ++++++++ >> include/uapi/linux/keyctl.h | 3 ++ >> 4 files changed, 75 insertions(+) >> >> diff --git a/Documentation/security/keys/core.rst >> b/Documentation/security/keys/core.rst >> index d224fd0..9b69a1f 100644 >> --- a/Documentation/security/keys/core.rst >> +++ b/Documentation/security/keys/core.rst >> @@ -1688,6 +1688,60 @@ The structure has a number of fields, some of >> which are mandatory: >> If successful, 0 will be returned. If the key doesn't support >> this, >> EOPNOTSUPP will be returned. >> + * ``int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, >> void *out);`` >> + * ``int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, >> const void *in, void *out);`` >> + >> + These methods are optional. If provided the first allows to >> generate the >> + public key pair corresponding to the private key. The second >> method allows >> + to generate a shared secret by combining the private key and >> the other >> + party's public key. >> + >> + In all cases, the following information is provided in the >> params block:: >> + >> + struct kernel_kpp_query { >> + struct key *key; >> + __u32 in_len; /* Input data size */ >> + __u32 out_len; /* Output buffer size */ >> + } >> + > > Probably not a huge deal as most common key sizes are already supported, > but... is there a way to query supported key sizes? I think for > DH_COMPUTE we didn't have this problem as everything was done in > software. However, if the intent is to use TPM / other hardware engines > we might need a way to query supported key sizes. Oh, there's a typo here, this structure should have been named 'kernel_kpp_params' and not 'kernel_kpp_query'. 'kernel_kpp_query' is defined below, it provides a way for determining the maximum supported key size. > >> + This includes the key to be used and the sizes in bytes of the >> input and >> + output buffers. >> + >> + For a given operation, the in and out buffers are used as follows:: >> + >> + Operation ID in,in_len out,out_len >> + ======================= =================== >> ======================== >> + KEYCTL_KPP_GEN_PUBKEY - Corresponding >> public key >> + KEYCTL_KPP_COMPUTE_SS Pair's public key Shared Secret >> + >> + If successful, the public key generation and the shared secret >> computation >> + will return the amount of data written into the output buffer. >> + >> + * ``int (*asym_kpp_query)(const struct kernel_kpp_params *params, >> struct kernel_kpp_query *res);`` >> + >> + This method is optional. If provided it allows information about >> the >> + asymmetric KPP (Key Protocol Primitives) key held in the key to be >> + determined. >> + >> + The ``params`` block will contain the key to be queried. >> ``in_len`` and >> + ``out_len`` are unused. >> + >> + If successful, the following information is filled in:: >> + >> + struct kernel_kpp_query { >> + __u32 supported_ops; /* Which ops are >> supported */ >> + __u32 max_size; /* Maximum size of the >> output buffer */ >> + }; >> + >> + The supported_ops field will contain a bitmask indicating what >> operations >> + are supported by the key, including public key generation and >> shared >> + secret computation. The following constants are defined for this:: >> + >> + KEYCTL_SUPPORTS_{GEN_PUBKEY, COMPUTE_SS}; >> + >> + If successful, 0 is returned. If the key is not an asymmetric >> kpp key, >> + EOPNOTSUPP is returned. >> + >> Request-Key Callback Service >> ============================ >> diff --git a/include/linux/key-type.h b/include/linux/key-type.h >> index bc9af55..d354b6b 100644 >> --- a/include/linux/key-type.h >> +++ b/include/linux/key-type.h >> @@ -19,6 +19,8 @@ >> struct kernel_pkey_query; >> struct kernel_pkey_params; >> +struct kernel_kpp_query; >> +struct kernel_kpp_params; >> /* >> * key under-construction record >> @@ -165,6 +167,11 @@ struct key_type { >> const void *in, void *out); >> int (*asym_verify_signature)(struct kernel_pkey_params *params, >> const void *in, const void *in2); >> + int (*asym_kpp_query)(const struct kernel_kpp_params *params, >> + struct kernel_kpp_query *res); >> + int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void >> *out); >> + int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, >> + const void *in, void *out); >> /* internal fields */ >> struct list_head link; /* link in types list */ >> diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h >> index e89b4a4..8f464ea 100644 >> --- a/include/linux/keyctl.h >> +++ b/include/linux/keyctl.h >> @@ -43,4 +43,15 @@ struct kernel_pkey_params { >> enum kernel_pkey_operation op : 8; >> }; >> +struct kernel_kpp_query { >> + __u32 supported_ops; /* Which ops are supported */ >> + __u32 max_size; /* Maximum size of the output buffer */ >> +}; >> + >> +struct kernel_kpp_params { >> + struct key *key; >> + __u32 in_len; /* Input data size */ >> + __u32 out_len; /* Output buffer size */ >> +}; >> + >> #endif /* __LINUX_KEYCTL_H */ >> diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h >> index d75d208..98b79f8 100644 >> --- a/include/uapi/linux/keyctl.h >> +++ b/include/uapi/linux/keyctl.h >> @@ -107,4 +107,7 @@ struct keyctl_pkey_params { >> __u32 __spare[7]; >> }; >> +#define KEYCTL_SUPPORTS_GEN_PUBKEY 0x0f > > This looks fishy, the other KEYCTL_SUPPORTS_ block ends at 0x08. This > would imply that KPP supports encryption, decryption, sign, verify. Do > you mean 0x10 here? > of course, thanks! >> +#define KEYCTL_SUPPORTS_COMPUTE_SS 0x10 >> + > > And 0x20 here? you're right, thanks! Best, ta
diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst index d224fd0..9b69a1f 100644 --- a/Documentation/security/keys/core.rst +++ b/Documentation/security/keys/core.rst @@ -1688,6 +1688,60 @@ The structure has a number of fields, some of which are mandatory: If successful, 0 will be returned. If the key doesn't support this, EOPNOTSUPP will be returned. + * ``int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void *out);`` + * ``int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, const void *in, void *out);`` + + These methods are optional. If provided the first allows to generate the + public key pair corresponding to the private key. The second method allows + to generate a shared secret by combining the private key and the other + party's public key. + + In all cases, the following information is provided in the params block:: + + struct kernel_kpp_query { + struct key *key; + __u32 in_len; /* Input data size */ + __u32 out_len; /* Output buffer size */ + } + + This includes the key to be used and the sizes in bytes of the input and + output buffers. + + For a given operation, the in and out buffers are used as follows:: + + Operation ID in,in_len out,out_len + ======================= =================== ======================== + KEYCTL_KPP_GEN_PUBKEY - Corresponding public key + KEYCTL_KPP_COMPUTE_SS Pair's public key Shared Secret + + If successful, the public key generation and the shared secret computation + will return the amount of data written into the output buffer. + + * ``int (*asym_kpp_query)(const struct kernel_kpp_params *params, struct kernel_kpp_query *res);`` + + This method is optional. If provided it allows information about the + asymmetric KPP (Key Protocol Primitives) key held in the key to be + determined. + + The ``params`` block will contain the key to be queried. ``in_len`` and + ``out_len`` are unused. + + If successful, the following information is filled in:: + + struct kernel_kpp_query { + __u32 supported_ops; /* Which ops are supported */ + __u32 max_size; /* Maximum size of the output buffer */ + }; + + The supported_ops field will contain a bitmask indicating what operations + are supported by the key, including public key generation and shared + secret computation. The following constants are defined for this:: + + KEYCTL_SUPPORTS_{GEN_PUBKEY, COMPUTE_SS}; + + If successful, 0 is returned. If the key is not an asymmetric kpp key, + EOPNOTSUPP is returned. + Request-Key Callback Service ============================ diff --git a/include/linux/key-type.h b/include/linux/key-type.h index bc9af55..d354b6b 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h @@ -19,6 +19,8 @@ struct kernel_pkey_query; struct kernel_pkey_params; +struct kernel_kpp_query; +struct kernel_kpp_params; /* * key under-construction record @@ -165,6 +167,11 @@ struct key_type { const void *in, void *out); int (*asym_verify_signature)(struct kernel_pkey_params *params, const void *in, const void *in2); + int (*asym_kpp_query)(const struct kernel_kpp_params *params, + struct kernel_kpp_query *res); + int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void *out); + int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, + const void *in, void *out); /* internal fields */ struct list_head link; /* link in types list */ diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h index e89b4a4..8f464ea 100644 --- a/include/linux/keyctl.h +++ b/include/linux/keyctl.h @@ -43,4 +43,15 @@ struct kernel_pkey_params { enum kernel_pkey_operation op : 8; }; +struct kernel_kpp_query { + __u32 supported_ops; /* Which ops are supported */ + __u32 max_size; /* Maximum size of the output buffer */ +}; + +struct kernel_kpp_params { + struct key *key; + __u32 in_len; /* Input data size */ + __u32 out_len; /* Output buffer size */ +}; + #endif /* __LINUX_KEYCTL_H */ diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h index d75d208..98b79f8 100644 --- a/include/uapi/linux/keyctl.h +++ b/include/uapi/linux/keyctl.h @@ -107,4 +107,7 @@ struct keyctl_pkey_params { __u32 __spare[7]; }; +#define KEYCTL_SUPPORTS_GEN_PUBKEY 0x0f +#define KEYCTL_SUPPORTS_COMPUTE_SS 0x10 + #endif /* _LINUX_KEYCTL_H */
Provide three new operations in the key_type struct that can be used to provide access to kpp operations. These will be implemented for the asymmetric key type in a later patch and may refer to a key retained in RAM by the kernel or a key retained in crypto hardware. int (*asym_kpp_query)(const struct kernel_kpp_params *params, struct kernel_kpp_query *res); int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void *out); int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, const void *in, void *out); Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> --- Documentation/security/keys/core.rst | 54 ++++++++++++++++++++++++++++++++++++ include/linux/key-type.h | 7 +++++ include/linux/keyctl.h | 11 ++++++++ include/uapi/linux/keyctl.h | 3 ++ 4 files changed, 75 insertions(+)