<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="info" docName="draft-ocf-v1" ipr="none">
  <front>
    <title abbrev="OCF v1.0">Open Cryptographic Framework</title>

    <author fullname="Michael Richardson" initials="M." surname="Richardson">
      <organization></organization>
    </author>

    <date day="01" month="April" year="2006" />

    <abstract>
      <t>This document describes an internal API applicable to the Linux and
      FreeBSD operating systems. It describes an asynchronous interface to
      encryption, authentication (hash) and compression algorithms. This
      document describes current practice, and extends the interface to
      include compression algorithms.</t>
    </abstract>

    <note title="Requirements Language">
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
      document are to be interpreted as described in <xref
      target="RFC2119">RFC 2119</xref>.</t>
    </note>
  </front>

  <middle>
    <section title="Introduction">
      <t>There are a variety of different encryption, authentication and
      compression algorithms. They may be implemented in software, hardware or
      various combinations. To facilitate interchange of different algorithms
      into network, harddisk, and user-space applications a standard interface
      to different methods is required.</t>
    </section>

    <section title="Overview of API">
      <t>This section describes what the API looks like, from a walk-through
      perspective.</t>

      <t>A kernel subsystem wishing to make use of one of the algorithms
      provided by OCF 1.0 should first create a session with
      crypto_newsession(). This returns an OCF cryptoid, which is an opaque
      64-bit handle to the driver and session within that driver.</t>

      <t>To submit the work, a "struct cryptop" structure is allocated (two
      are required for encryption and integrity operations), and each are
      filled in, a callback function is provided, and then crypto_dispatch()
      is called. The callback function is provided with an opaque application
      specific pointer.</t>
    </section>

    <section title="Method descriptions - caller interface">
      <section title="new section">
        <t>#include &lt;opencrypto/cryptodev.h&gt; </t>
      </section>

      <section title="new section">
        <t>extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri,
        int hard);</t>
      </section>

      <section title="new section">
        <t> extern int crypto_freesession(u_int64_t sid);</t>
      </section>

      <section title="new section">
        <t> extern int32_t crypto_get_driverid(u_int32_t flags);</t>
      </section>

      <section title="new section">
        <t> extern int crypto_register(u_int32_t driverid, int alg, u_int16_t
        maxoplen, u_int32_t flags, int (*newses)(void*, u_int32_t*, struct
        cryptoini*), int (*freeses)(void*, u_int64_t), int (*process)(void*,
        struct cryptop *, int), void *arg);</t>
      </section>

      <section title="new section">
        <t> extern int crypto_kregister(u_int32_t, int, u_int32_t, int
        (*)(void*, struct cryptkop *, int), void *arg); </t>
      </section>

      <section title="new section">
        <t>extern int crypto_unregister(u_int32_t driverid, int alg); extern
        int crypto_unregister_all(u_int32_t driverid); </t>
      </section>

      <section title="new section">
        <t>extern int crypto_dispatch(struct cryptop *crp); </t>
      </section>

      <section title="new section">
        <t>extern int crypto_kdispatch(struct cryptkop *); #define CRYPTO_SYMQ
        0x1 #define CRYPTO_ASYMQ 0x2 </t>
      </section>

      <section title="new section">
        <t>extern int crypto_unblock(u_int32_t, int); </t>
      </section>

      <section title="new section">
        <t>extern void crypto_done(struct cryptop *crp); </t>
      </section>

      <section title="new section">
        <t>extern void crypto_kdone(struct cryptkop *); </t>
      </section>

      <section title="new section">
        <t>extern int crypto_getfeat(int *); </t>
      </section>

      <section title="new section">
        <t>extern void crypto_freereq(struct cryptop *crp); </t>
      </section>

      <section title="new section">
        <t>extern struct cryptop *crypto_getreq(int num); </t>
      </section>

      <section title="new section">
        <t>int crypto_newsession(); </t>
      </section>

      <t>Called by consumers of cryptographic services (such as the IPsec
      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 (keys, algorithms, offsets, etc. </t>

      <t>The third argument indicates whether only hardware acceleration is
      acceptable. </t>

      <t>* int crypto_freesession(); </t>

      <t>Called to disestablish a previously-established session. </t>

      <t>* int crypto_dispatch(); </t>

      <t>Called to process a request, encapsulated in its only argument. The
      various fields in that structure contain: </t>

      <t><list>
          <t>The SID. o The total length in bytes of the buffer to be
          processed</t>

          <t></t>
        </list>o The total length of the result, which for symmetric crypto
      operations will be the same as the input length. </t>

      <t>o The type of input buffer, as used in the kernel malloc() routine.
      This will be used if the framework needs to allocate a new buffer for
      the result (or for re-formatting the input). </t>

      <t>o The routine that the OCF should invoke upon completion of the
      request, whether successful or not. </t>

      <t>o The error type, if any errors were encountered. If the EAGAIN error
      code is returned, the SID has changed. The consumer should record the
      new SID and use it in all subsequent requests. In this case, the request
      may be re-submitted 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). </t>

      <t>o A bitmask of flags associated with this request. Currently, the
      only flag defined is CRYPTO_F_IMBUF, which indicates that the input
      buffer is an mbuf chain. </t>

      <t>o The input and output buffers. The input buffer may be an mbuf chain
      or a contiguous buffer (as identified by the flags). The output buffer
      will be of the same type. </t>

      <t>o A pointer to opaque data. This is passed through the crypto
      framework untouched and is intended for the invoking application's use.
      </t>

      <t>o A linked list of operation descriptors, which indicate what
      operations should be applied, and in what sequence, to the input data.
      The descriptors indicate where each operation should start, the length
      of the data to be processed, where on the output buffer should the
      results be placed, the key material to be used, and various
      operation-specific flags (e.g., what Initialization Vector to use for
      CBC-mode encryption). </t>

      <section title="new section">
        <t>* int crypto_kdispatch(); </t>
      </section>

      <t>Similar to crypto_dispatch(), for public-key operations. </t>

      <t></t>
    </section>

    <section title="method descriptions - driver interface">
      <t>* int32_t crypto_get_driverid(); </t>

      <t>int crypto_register(); </t>

      <t>int crypto_kregister();</t>

      <t>int crypto_unregister();</t>

      <t> Used by device drivers to register and unregister symmetric and
      asymmetric algorithm support with the OCF. </t>

      <section title="new section">
        <t>void crypto_done(); </t>

        <t>void crypto_kdone();</t>

        <t>Called by device drivers on completion of a request (symmetric and
        asymmetric, respectively).</t>
      </section>
    </section>

    <section title="structure explanations">
      <t></t>
    </section>

    <section title="callback function requirements">
      <t></t>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t></t>
    </section>

    <section anchor="Acknowledgements" title="Acknowledgements">
      <t></t>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <?rfc include="reference.RFC.2119"?>
    </references>
  </back>
</rfc>