Krishna Yenduri's Weblog

Krishna Yenduri's Weblog

All | General | Solaris

20050805 Friday August 05, 2005

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

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, 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 uts/common/inet/ip/ipsecah.c.
   2826         AH_INIT_CALLREQ(&call_req);
   2827
   2828         ii->ipsec_in_skip_len = skip_len;
   2829
   2830         IPSEC_CTX_TMPL(assoc, ipsa_authtmpl, IPSEC_ALG_AUTH, ctx_tmpl);
   2831
   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);
   2836
   2837         switch (kef_rc) {
   2838         case CRYPTO_SUCCESS:
   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);
   2844                 return (IPSEC_STATUS_PENDING);
   2845         case CRYPTO_INVALID_MAC:
   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) {                                          \
   2778         (_cr)->cr_flag = CRYPTO_SKIP_REQID|CRYPTO_RESTRICTED;           \
   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, ah_kcf_callback(), which kCF will call after completing the operation. The call back routine gets two arguments - cr_callback_arg (in this case ipsec_mp) and  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 crypto_mac_verify().

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.

1crypto_mac_verify() 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:
Technorati Tag:


( Aug 05 2005, 09:15:59 AM PDT / Aug 05 2005, 07:57:45 AM PDT ) Permalink
Trackback: http://blogs.sun.com/yenduri/entry/how_to_use_crypto_api1

Comments:

Post a Comment:

Comments are closed for this entry.

« May 2008
SunMonTueWedThuFriSat
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
       
Today


XML




    Blogroll


Today's Page Hits: 11