*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->OpenBSD man pages -> crypto_dispatch (9)              
Title
Content
Arch
Section
 

CRYPTO(9)

Contents


NAME    [Toc]    [Back]

     crypto - API for cryptographic services in the kernel

SYNOPSIS    [Toc]    [Back]

     #include <crypto/cryptodev.h>

     int32_t
     crypto_get_driverid(u_int8_t);

     int
     crypto_register(u_int32_t, int *,
             int  (*)(u_int32_t  *,  struct  cryptoini  *),   int
(*)(u_int64_t),
             int (*)(struct cryptop *));

     int
     crypto_kregister(u_int32_t,  int  *, int (*)(struct cryptkop
*));

     int
     crypto_unregister(u_int32_t, int);

     void
     crypto_done(struct cryptop *);

     void
     crypto_kdone(struct cryptkop *);

     int
     crypto_newsession(u_int64_t *, struct cryptoini *, int);

     int
     crypto_freesession(u_int64_t);

     int
     crypto_dispatch(struct cryptop *);

     int
     crypto_kdispatch(struct cryptkop *);

     struct cryptop *
     crypto_getreq(int);

     void
     crypto_freereq(struct cryptop *);

     #define EALG_MAX_BLOCK_LEN      16

     struct cryptoini {
             int                cri_alg;
             int                cri_klen;
             int                cri_rnd;
             caddr_t            cri_key;
             u_int8_t           cri_iv[EALG_MAX_BLOCK_LEN];
             struct cryptoini  *cri_next;
     };

     struct cryptodesc {
             int                crd_skip;
             int                crd_len;
             int                crd_inject;
             int                crd_flags;
             struct cryptoini   CRD_INI;
             struct cryptodesc *crd_next;
     };

     struct cryptop {
             u_int64_t          crp_sid;
             int                crp_ilen;
             int                crp_olen;
             int                crp_alloctype;
             int                crp_etype;
             int                crp_flags;
             caddr_t            crp_buf;
             caddr_t            crp_opaque;
             struct cryptodesc *crp_desc;
             int              (*crp_callback)(struct cryptop *);
             struct cryptop    *crp_next;
             caddr_t            crp_mac;
     };

     struct crparam {
             caddr_t         crp_p;
             u_int           crp_nbits;
     };

     #define CRK_MAXPARAM    8

     struct cryptkop {
             u_int                 krp_op;             /*     ie.
CRK_MOD_EXP or other */
             u_int               krp_status;     /* return status
*/
             u_short            krp_iparams;    /* # of input parameters */
             u_short             krp_oparams;     /*  # of output
parameters */
             u_int32_t          krp_hid;
             struct crparam     krp_param[CRK_MAXPARAM];       /*
kvm */
             int                 (*krp_callback)(struct  cryptkop
*);
             struct cryptkop   *krp_next;
     };

DESCRIPTION    [Toc]    [Back]

     crypto is a framework for drivers of cryptographic  hardware
to register
     with  the  kernel so ``consumers'' (other kernel subsystems,
and eventually
     users through an appropriate device) are able to make use of
it.  Drivers
     register with the framework the algorithms they support, and
provide entry
 points (functions) the framework may call to  establish,
use, and tear
     down sessions.  Sessions are used to cache cryptographic information in a
     particular driver (or associated hardware),  so  initialization is not
     needed  with every request.  Consumers of cryptographic services pass a
     set of descriptors that  instruct  the  framework  (and  the
drivers registered
  with  it) of the operations that should be applied on
the data (more
     than one cryptographic operation can be requested).

     Keying operations are supported as well.  Unlike the symmetric operators
     described  above,  these sessionless commands perform mathematical operations
 using input and output parameters.

     Since the consumers may not be associated  with  a  process,
drivers may not
     use  tsleep(9).   The same holds for the framework.  Thus, a
callback mechanism
 is used to notify a consumer that a request  has  been
completed (the
     callback  is specified by the consumer on an per-request basis).  The
     callback is invoked by the framework whether the request was
successfully
     completed  or  not.   An error indication is provided in the
latter case.  A
     specific error code, EAGAIN, is used to indicate that a session number
     has changed and that the request may be re-submitted immediately with the
     new session number.  Errors are only returned to the  invoking function if
     not  enough  information  to  call the callback is available
(meaning, there
     was a fatal error in verifying the arguments).  For  session
initialization
 and teardown there is no callback mechanism used.

     The  crypto_newsession()  routine  is called by consumers of
cryptographic
     services (such as the ipsec(4) stack) that wish to establish
a new session
  with  the  framework.   On success, the first argument
will contain the
     Session Identifier (SID).  The second argument contains  all
the necessary
     information  for  the  driver to establish the session.  The
third argument
     indicates whether a hardware driver should be  used  (1)  or
not (0).  The
     various fields in the cryptoini structure are:

     cri_alg        Contains  an algorithm identifier.  Currently
supported algorithms
 are:

                   CRYPTO_DES_CBC
                   CRYPTO_3DES_CBC
                   CRYPTO_BLF_CBC
                   CRYPTO_CAST_CBC
                   CRYPTO_SKIPJACK_CBC
                   CRYPTO_MD5_HMAC
                   CRYPTO_SHA1_HMAC
                   CRYPTO_RIPEMD160_HMAC
                   CRYPTO_MD5_KPDK
                   CRYPTO_SHA1_KPDK
                   CRYPTO_AES_CBC
                   CRYPTO_ARC4
                   CRYPTO_MD5
                   CRYPTO_SHA1

     cri_klen      Specifies the length of the key in  bits,  for
variable-size
                   key algorithms.

     cri_rnd       Specifies the number of rounds to be used with
the algorithm,
 for variable-round algorithms.

     cri_key       Contains the key to be  used  with  the  algorithm.

     cri_iv         Contains  an  explicit  initialization vector
(IV), if it does
                   not prefix the data.  This  field  is  ignored
during initialization.
   If  no IV is explicitly passed (see
below on details),
 a random IV  is  used  by  the  device
driver processing
                   the request.

     cri_next      Contains a pointer to another cryptoini structure.  Multiple
 such structures may be linked to establish
multi-algorithm
  sessions  (ipsec(4)  is an example consumer of such a
                   feature).

     The cryptoini structure and its contents will not  be  modified by the
     framework  (or  the  drivers used).  Subsequent requests for
processing that
     use the SID returned will avoid the cost of  re-initializing
the hardware
     (in  essence,  SID  acts as an index in the session cache of
the driver).

     crypto_freesession() is called with the SID returned by
     crypto_newsession() to disestablish the session.

     crypto_dispatch() is called to process a request.  The various fields in
     the cryptop structure are:

     crp_sid        Contains the SID.

     crp_ilen        Indicates  the  total length in bytes of the
buffer to be
                    processed.

     crp_olen       On return, contains the length of the result,
not including
  crd_skip.   For  symmetric crypto operations, this will
                    be the same as the input length.

     crp_alloctype  Indicates the type of buffer, as used in  the
kernel
                    malloc(9)  routine.  This will be used if the
framework
                    needs to allocate a new buffer for the result
(or for reformatting
 the input).

     crp_callback    This  routine  is invoked upon completion of
the request,
                    whether successful or  not.   It  is  invoked
through the
                    crypto_done()  routine.   If  the request was
not successful,
                    an error code is set in the crp_etype  field.
It is the
                    responsibility of the callback routine to set
the appropriate
 spl(9) level.

     crp_etype      Contains the error type, if any  errors  were
encountered,
                    or  zero if the request was successfully processed.  If the
                    EAGAIN error code is returned,  the  SID  has
changed (and
                    has been recorded in the crp_sid field).  The
consumer
                    should record the new SID and use it  in  all
subsequent requests.
  In this case, the request may be resubmitted immediately.
  This mechanism  is  used  by  the
framework to
                    perform  session  migration  (move  a session
from one driver
                    to another, because of availability,  performance, or other
                    considerations).

                    Note  that  this  field only makes sense when
examined by the
                    callback routine specified  in  crp_callback.
Errors are
                    returned  to  the invoker of crypto_process()
only when
                    enough information is not present to call the
callback
                    routine  (i.e., if the pointer passed is NULL
or if no
                    callback routine was specified).

     crp_flags      Is a bitmask of flags  associated  with  this
request.  Currently
 defined flags are:

                    CRYPTO_F_IMBUF   The  buffer  pointed  to  by
crp_buf is an
                                    mbuf chain.

     crp_buf        Points to the input buffer.  On return  (when
the callback
                    is  invoked),  it  contains the result of the
request.  The
                    input buffer may be an mbuf chain or  a  contiguous buffer
                    (of  a type identified by crp_alloctype), depending on
                    crp_flags.

     crp_opaque     This is passed through the  crypto  framework
untouched and
                    is  intended  for  the invoking application's
use.

     crp_desc       This is a linked list of  descriptors.   Each
descriptor
                    provides information about what type of cryptographic operation
 should be done on the  input  buffer.
The various
                    fields are:

                    crd_skip
                      The  offset  in the input buffer where processing should
                      start.

                    crd_len
                      How many bytes, after crd_skip,  should  be
processed.

                    crd_inject
                      Offset  from the beginning of the buffer to
insert any
                      results.  For encryption  algorithms,  this
is where the
                      initialization vector (IV) will be inserted
when encrypting
 or where it can be found when  decrypting (subject
  to  crd_flags).   For MAC algorithms,
this is where
                      the result of the keyed hash  will  be  inserted.

                    crd_flags
                      The following flags are defined:

                      CRD_F_ENCRYPT        For  encryption  algorithms, this bit
                                         is set  when  encryption
is required
                                         (when  not  set, decryption is performed).


                      CRD_F_IV_PRESENT    For  encryption   algorithms, this bit
                                         is  set  when the IV already precedes
                                         the   data,    so    the
crd_inject value
                                         will  be  ignored and no
IV will be
                                         written in  the  buffer.
Otherwise,
                                         the  IV  used to encrypt
the packet
                                         will be written  at  the
location
                                         pointed       to      by
crd_inject.  The IV
                                         length is assumed to  be
equal to the
                                         blocksize of the encryption algorithm.
   Some   applications that do
                                         special  ``IV cooking'',
such as the
                                         half-IV     mode      in
ipsec(4), can use
                                         this  flag  to  indicate
that the IV
                                         should not be written on
the packet.
                                         This  flag  is typically
used in conjunction
    with     the
CRD_F_IV_EXPLICIT
                                         flag.

                      CRD_F_IV_EXPLICIT    For  encryption  algorithms, this bit
                                         is set when  the  IV  is
explicitly provided
 by the consumer in
the crd_iv
                                         fields.  Otherwise,  for
encryption
                                         operations   the  IV  is
provided for by
                                         the driver used to  perform the operation,
  whereas  for  decryption operations
 it is  pointed  to
by the
                                         crd_inject  field.  This
flag is typically
 used when  the  IV
is calculated
                                         ``on  the  fly''  by the
consumer, and
                                         does not precede the data (some
                                         ipsec(4) configurations,
and the encrypted
  swap  are   two
such examples).

                      CRD_F_COMP          For  compression  algorithms, this bit
                                         is set when  compression
is required
                                         (when  not  set,  decompression is performed).


                    CRD_INI
                      This cryptoini structure will not be  modified by the
                      framework  or  the  device  drivers.  Since
this information
                      accompanies every  cryptographic  operation
request,
                      drivers  may  re-initialize state on-demand
(typically an
                      expensive  operation).   Furthermore,   the
cryptographic
                      framework may re-route requests as a result
of full
                      queues or hardware  failure,  as  described
above.

                    crd_next
                      Point to the next descriptor.  Linked operations are
                      useful in protocols such as ipsec(4), where
multiple
                      cryptographic  transforms may be applied on
the same
                      block of data.

     crypto_getreq() allocates a cryptop structure with a  linked
list of as
     many cryptodesc structures as were specified in the argument
passed to
     it.

     crypto_freereq() deallocates a  structure  cryptop  and  any
cryptodesc
     structures linked to it.  Note that it is the responsibility
of the callback
 routine to do the necessary  cleanups  associated  with
the opaque
     field in the cryptop structure.

     crypto_kdispatch()  is called to perform a keying operation.
The various
     fields in the cryptkop structure are:

     krp_op         Operation code, such as CRK_MOD_EXP.

     krp_status     Return code.  This errno-style variable indicates whether
                    there  were lower level reasons for operation
failure.

     krp_iparams    Number of input parameters to  the  specified
operation.
                    Note  that  each  operation  has a (typically
hardwired) number
 of such parameters.

     krp_oparams    Number of output parameters from  the  specified operation.
                    Note  that  each  operation  has a (typically
hardwired) number
 of such parameters.

     krp_kvp        An array of kernel memory  blocks  containing
the parameters.


     krp_hid         Identifier specifying which low-level driver
is being
                    used.

     krp_callback   Callback called on completion of a keying operation.

DRIVER-SIDE API    [Toc]    [Back]

     The         crypto_get_driverid(),        crypto_register(),
crypto_kregister(),
     crypto_unregister(), and crypto_done() routines are used  by
drivers that
     provide support for cryptographic primitives to register and
unregister
     with the kernel crypto  services  framework.   Drivers  must
first use the
     crypto_get_driverid() function to acquire a driver identifier, specifying
     the cc_flags as an argument (normally 0,  but  software-only
drivers should
     specify CRYPTOCAP_F_SOFTWARE).  For each algorithm the driver supports,
     it must then call crypto_register().  The first argument  is
the driver
     identifier.  The second argument is an array of CRYPTO_ALGORITHM_MAX + 1
     elements, indicating which algorithms  are  supported.   The
last three arguments
 are pointers to three driver-provided functions that
the framework
 may call to establish new  cryptographic  context  with
the driver,
     free  already  established context, and ask for a request to
be processed
     (encrypt, decrypt, etc.) crypto_unregister()  is  called  by
drivers that
     wish  to  withdraw  support for an algorithm.  The two arguments are the
     driver and algorithm identifiers, respectively.   Typically,
drivers for
     pcmcia(4)  crypto  cards  that are being ejected will invoke
this routine
     for all algorithms supported by the card.  If called with
     CRYPTO_ALGORITHM_ALL, all algorithms registered for a driver
will be unregistered
 in one go and the driver will be disabled (no new
sessions
     will be allocated on that driver, and any existing  sessions
will be migrated
  to other drivers).  The same will be done if all algorithms associated
 with a driver are unregistered one by one.

     The calling convention for the  three  driver-supplied  routines is:

     int (*newsession) (u_int32_t *, struct cryptoini *);
     int (*freesession) (u_int64_t);
     int (*process) (struct cryptop *);
     int (*kprocess) (struct cryptkop *);

     On  invocation,  the first argument to newsession() contains
the driver
     identifier obtained via crypto_get_driverid().  On  successfully returning,
 it should contain a driver-specific session identifier.
The second
     argument is identical to that of crypto_newsession().

     The freesession() routine takes as argument the  SID  (which
is the concatenation
  of the driver identifier and the driver-specific
session identifier).
  It should clear any context  associated  with  the
session (clear
     hardware registers, memory, etc.).

     The  process()  routine is invoked with a request to perform
crypto processing.
  This routine must not block, but should queue  the
request and
     return  immediately.  Upon processing the request, the callback routine
     should be invoked.  In case of error, the  error  indication
must be placed
     in  the  crp_etype field of the cryptop structure.  When the
request is
     completed, or an error is detected,  the  process()  routine
should invoke
     crypto_done().   Session migration may be performed, as mentioned previously.


     The kprocess() routine is invoked with a request to  perform
crypto key
     processing.   This  routine must not block, but should queue
the request
     and return immediately.  Upon processing  the  request,  the
callback routine
 should be invoked.  In case of error, the error indication must be
     placed in the krp_status field of  the  cryptkop  structure.
When the request
  is completed, or an error is detected, the kprocess()
routine
     should invoke crypto_kdone().

RETURN VALUES    [Toc]    [Back]

     crypto_register(), crypto_kregister(), crypto_unregister(),
     crypto_newsession(), and crypto_freesession()  return  0  on
success, or an
     error code on failure.  crypto_get_driverid() returns a nonnegative value
 on error, and -1 on failure.  crypto_getreq()  returns  a
pointer to a
     cryptop  structure  and  NULL on failure.  crypto_dispatch()
returns EINVAL
     if its argument or the callback function  was  NULL,  and  0
otherwise.  The
     callback  is provided with an error code in case of failure,
in the
     crp_etype field.

FILES    [Toc]    [Back]

     sys/crypto/crypto.c  most of the framework code

SEE ALSO    [Toc]    [Back]

      
      
     ipsec(4), pcmcia(4), malloc(9), tsleep(9)

HISTORY    [Toc]    [Back]

     The cryptographic framework first appeared  in  OpenBSD  2.7
and was written
     by Angelos D. Keromytis <angelos@openbsd.org>.

BUGS    [Toc]    [Back]

     The framework currently assumes that all the algorithms in a
     crypto_newsession() operation must be available by the  same
driver.  If
     that's not the case, session initialization will fail.

     The  framework  also needs a mechanism for determining which
driver is best
     for a specific set of algorithms associated with a  session.
Some type of
     benchmarking is in order here.

     Multiple instances of the same algorithm in the same session
are not supported.
  Note that 3DES is considered one algorithm (and not
three instances
  of  DES).  Thus, 3DES and DES could be mixed in the
same request.

     A queue for completed operations should be  implemented  and
processed at
     some  software spl(9) level, to avoid overall system latency
issues, and
     potential kernel stack exhaustion while processing  a  callback.

     When SMP time comes, we will support use of a second processor (or more)
     as a crypto device (this is actually AMP, but  we  need  the
same basic support).


OpenBSD      3.6                          April      21,     2000
[ Back ]
 Similar pages
Name OS Title
krs HP-UX kernel registry services
krsd HP-UX kernel registry services daemon
krs_flush HP-UX flush kernel registry services data to disk
getservent_r Tru64 Get a services file entry from the /etc/services file.
getservent Tru64 Get a services file entry from the /etc/services file.
DSAparams_print_fp Tru64 Print cryptographic parameters
RSA_print OpenBSD print cryptographic parameters
crypto Tru64 OpenSSL cryptographic library
crypto OpenBSD OpenSSL cryptographic library
RSA_print Tru64 Print cryptographic parameters
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service