How to use crypto API in Solaris kernel code - Part 2

Guest Author

How to use crypto API in Solaris kernel code - Part 2

Continuing from my previous post, we look at how to use the crypto API
in the asynchronous case. The header file, href="http://cvs.opensolaris.org/source/xref/usr/src/uts/common/sys/crypto/api.h">uts/common/sys/crypto/api.h
defines the crypto_call_req_t structure that needs to be passed in the
asynchronous case. I am including a man page
style description of this structure here.

As described in the man page, the default behavior is what is called an
adaptive asynchronous mode (CRYPTO_ALWAYS_QUEUE flag is clear) as
opposed to pure asynchronous mode (CRYPTO_ALWAYS_QUEUE flag is
set).  kCF consists of various crypto providers some of them
software-based and some
of them hardware-based. For a given mechanism, a software provider is
typically capable of doing the operation without needing kCF to block.
The default behavior is appropriate for an operation like digest or MAC
which do not take too many cycles. It may not be appropriate for
operations like encrypt/decrypt, especially for public key ciphers like
RSA. The caller needs to determine which behavior is suited for its
case. In the default case, a caller is required to handle a
CRYPTO_SUCCESS return value. Of course, if the CRYPTO_ALWAYS_QUEUE flag
is set, this is not the case.

Looking at the ah_submit_req_inbound() code in href="http://cvs.opensolaris.org/source/xref/usr/src/uts/common/inet/ip/ipsecah.c">uts/common/inet/ip/ipsecah.c.

   2826         AH_INIT_CALLREQ(&call_req);
2828 ii->ipsec_in_skip_len = skip_len;
2830 IPSEC_CTX_TMPL(assoc, ipsa_authtmpl, IPSEC_ALG_AUTH, ctx_tmpl);
2832 /\* call KEF to do the MAC operation \*/
2833 kef_rc = crypto_mac_verify(&assoc->ipsa_amech,
2834 &ii->ipsec_in_crypto_data, &assoc->ipsa_kcfauthkey, ctx_tmpl,
2835 &ii->ipsec_in_crypto_mac, &call_req);
2837 switch (kef_rc) {
2839 AH_BUMP_STAT(crypto_sync);
2840 return (ah_auth_in_done(ipsec_mp));
2841 case CRYPTO_QUEUED:
2842 /\* ah_callback() will be invoked on completion \*/
2843 AH_BUMP_STAT(crypto_async);
2846 AH_BUMP_STAT(crypto_sync);
2847 ah_log_bad_auth(ipsec_mp);
2848 return (IPSEC_STATUS_FAILED);
2849 }

The call_req argument to crypto_mac_verify() is the one that is of
interest here1. One thing to
notice here is that
this routine,  ah_submit_req_inbound()
can be called from interrupt context while processing the incoming
IPSec packet. So, we ensure we won't be blocking by calling
crypto_mac_verify() in asynchronous mode. call_req is set on line 2826
with the following macro

   2777 #define AH_INIT_CALLREQ(_cr) {                                          \\
2779 if (ipsec_algs_exec_mode[IPSEC_ALG_AUTH] == IPSEC_ALGS_EXEC_ASYNC) \\
2780 (_cr)->cr_flag |= CRYPTO_ALWAYS_QUEUE; \\
2781 (_cr)->cr_callback_arg = ipsec_mp; \\
2782 (_cr)->cr_callback_func = ah_kcf_callback; \\
2783 }

We specify a call back routine,
which kCF will call after
completing the operation. The call back routine gets two arguments -
cr_callback_arg (in this case ipsec_mp) and  style="font-family: sans-serif;">a status of the crypto operation. The
call back routine must adhere  to  the same restrictions as a
driver soft interrupt handler. Note that this code sets
CRYPTO_ALWAYS_QUEUE flag conditionally
(default is that IPSEC_ALGS_EXEC_ASYNC is not set). This explains
why  we check for CRYPTO_SUCCESS on line 2838 after calling

This concludes a brief overview of using crypto API.  The best way
to get more details is to look at more code. You can find all the
consumers of these API by looking for files which include sys/crypto/api.h.

takes more arguments than crypto_digest() from our previous example.
The third argument is the key used for mac'ing. The fourth argument is
a context template which is used to precompute things like a key
schedule and reuse it several times later.

Technorati Tag: rel="tag">OpenSolaris

Technorati Tag: rel="tag">Solaris

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.