X

How to use crypto API in Solaris kernel code

Guest Author


http-equiv="content-type">How to use crypto API in Solaris kernel code


Now that OpenSolaris is a
reality, we can finally blog about the source code. I will start with
how to do crypto stuff from the kernel code.



Solaris 10 has the kernel crypto framework (kCF) which offers crypto
API for other kernel modules or drivers. IPSec and Kerberos are some of
the
components that make use of it. This API is not public yet and hence
you won't see any man pages (They should very likely be public in
Nevada). The complete list of API is in href="http://cvs.opensolaris.org/source/xref/usr/src/uts/common/sys/crypto/api.h">uts/common/sys/crypto/api.h.



Let us start with a simple digest operation. The digest API are

    crypto_digest()

    crypto_digest_init(), crypto_digest_update(),
crypto_digest_final()




If you are familiar with PKCS #11, these routines follow similar naming
conventions except that crypto_digest() does not need an
crypto_digest_init(). Let us look at crypto_digest(). The prototype is



    int crypto_digest(crypto_mechanism_t \*mech,
crypto_data_t \*data, crypto_data_t \*digest, crypto_call_req_t \*cr);



The structures are defined in href="http://cvs.opensolaris.org/source/xref/usr/src/uts/common/sys/crypto/common.h">uts/common/sys/crypto/common.h.
It is best to explain each argument by looking at an actual example.
Looking in href="http://cvs.opensolaris.org/source/xref/usr/src/uts/common/io/cryptmod.c">uts/common/io/cryptmod.c,
we find

 
692           
rv = crypto_digest(&mech, &d1, &d2, NULL);






The first argument specifies the cryptographic mechanism  to be
used and its parameters.



 672           
mech.cm_type = digest_type;

 673           
mech.cm_param = 0;

 674           
mech.cm_param_len = 0;




cm_type identifies the type of the mechanism. This field must be set to
the value returned by crypto_mech2id(). crypto_mech2id() gets the kCF
internal mechanism id assigned for a mechanism name. This call needs to
be made only once since the id stays the same till a reboot. For
example in this file, a
SHA1 mechanism id is obtained



 294         
sha1_hash_mech = crypto_mech2id(SUN_CKM_SHA1);




and it is passed as digest_type to the kef_digest() routine.



cm_param specifies the parameter for a mechanism. It is zero here. But,
it needs to be specified for some mechanisms. For example, the IV for a
CKM_DES_CBC mechanism is passed in this field. cm_param_len specifies
the length of cm_param, in bytes.





The second argument describes the data that is to be digested.



 676           
v1.iov_base = (void \*)input;

 677           
v1.iov_len = inlen;

 678

 679           
d1.cd_format = CRYPTO_DATA_RAW;

 680           
d1.cd_offset = 0;

 681           
d1.cd_length = v1.iov_len;

 682           
d1.cd_raw = v1;




cd_format specifies the format of the data which can be one of
CRYPTO_DATA_RAW, CRYPTO_DATA_UIO or CRYPTO_DATA_MBLK. CRYPTO_DATA_RAW
format means that the input is a iovec_t which basically means a
pointer to a buffer and its length. CRYPTO_DATA_MBLK format is useful
in networking code where mblk_t structures are common. cd_offset
specifies an offset from the beginning of the data. The digesting
starts at that offset byte. cd_length specifies the length of the data
to be used for the digesting. cd_raw is used to specify the address of
a iovec_t buffer. As can be guessed, this field  is valid only if
cd_format is equal to CRYPTO_DATA_RAW.





The third argument describes the output data.



 684           
v2.iov_base = (void \*)output;

 685           
v2.iov_len = hashlen;

 686

 687           
d2.cd_format = CRYPTO_DATA_RAW;

 688           
d2.cd_offset = 0;

 689           
d2.cd_length = v2.iov_len;

 690           
d2.cd_raw = v2;






The fourth argument describes the calling conditions.  A NULL
value, as is the case here, means that caller is prepared to block till
the operation completes. Callers in an interrupt context usually can't
block and need to specify a value for this argument making it an
asynchronous interface.



One asynchronous example is in href="http://cvs.opensolaris.org/source/xref/usr/src/uts/common/inet/ip/ipsecah.c">uts/common/inet/ip/ipsecah.c.
I will talk about it in my next post.



Technorati Tag:


Technorati Tag:



Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.