RFC 2628

Simple Cryptographic Program Interface (Crypto API)

๐Ÿ“… published June 1999, from ietf

Network Working Group ๐ŸŒธ Request for Comments: 2628

Author: V. Smyslov (TWS) ๐Ÿ’– Category: Informational โœจ Date: June 1999 ๐Ÿ“… Obsoletes / Updates: the title block doesn't list anything this one obsoletes or updates ๐Ÿฆ‹

Simple Cryptographic Program Interface (Crypto API) ๐ŸŽ€


Status of This Memo ๐Ÿงš

okay so this memo is for information only, bestie ๐Ÿ“–. It is not an Internet standard of any kind, so nobody is required to follow it ๐Ÿซถ. Distribution of this memo is unlimited ๐Ÿ’….

Copyright (C) The Internet Society (1999). All Rights Reserved. ๐Ÿ”’

Abstract โœจ

okay so this document describes a simple Application Program Interface to cryptographic functions ๐Ÿ”ฅ. The main purpose of such an interface is to separate cryptographic libraries from internet applications, which lets both sides be developed independently ๐Ÿฆ‹. It can be used in various internet applications such as [IPsec], [ISAKMP], [IKE], [TLS] ๐Ÿ’–.

Table of Contents ๐Ÿ“

   1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . .  2
   1.1. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . .  2
   1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . .  2
   1.3. Objectives of Development . . . . . . . . . . . . . . . . . .  3
   2. Cryptoplugin Structure. . . . . . . . . . . . . . . . . . . . .  3
   3. Program Interface . . . . . . . . . . . . . . . . . . . . . . .  4
   3.1. Cryptoplugin Initialization Function. . . . . . . . . . . . .  4
   3.1.1. Description of CryptoPluginInfo structure . . . . . . . . .  6
   3.1.2. Description of CryptoAlgInfo structure. . . . . . . . . . .  6
   3.2. Cryptoplugin Deinitialization Function. . . . . . . . . . . .  9
   3.3. Cryptographic Context Opening Function. . . . . . . . . . . . 10
   3.4. Cryptographic Context Reopening Function. . . . . . . . . . . 11
   3.5. Cryptographic Context Closing Function. . . . . . . . . . . . 12
   3.6. Key Verification Function . . . . . . . . . . . . . . . . . . 12
   3.7. Data Transformation Function. . . . . . . . . . . . . . . . . 13
   3.7.1. For CRYPTO_TYPE_ENCRYPT Algorithm Type. . . . . . . . . . . 13
   3.7.2. For CRYPTO_TYPE_DECRYPT Algorithm Type. . . . . . . . . . . 14
   3.7.3. For CRYPTO_TYPE_SIGN Algorithm Type . . . . . . . . . . . . 15
   3.7.4. For CRYPTO_TYPE_VERIFY Algorithm Type . . . . . . . . . . . 17
   3.7.5. For CRYPTO_TYPE_COMPRESS Algorithm Type . . . . . . . . . . 18
   3.7.6. For CRYPTO_TYPE_UNCOMPRESS Algorithm Type . . . . . . . . . 18
   3.7.7. For CRYPTO_TYPE_HASH Algorithm Type . . . . . . . . . . . . 19
   3.7.8. For CRYPTO_TYPE_RANDOM Algorithm Type.  . . . . . . . . . . 21
   3.8. Cryptographic Context Control Function. . . . . . . . . . . . 22
   4. Cryptoplugin Registration Procedure . . . . . . . . . . . . . . 23
   5. Security Considerations . . . . . . . . . . . . . . . . . . . . 23
   6. References. . . . . . . . . . . . . . . . . . . . . . . . . . . 23
   7. Author's Address  . . . . . . . . . . . . . . . . . . . . . . . 24
   Appendix A. The interface specification as a C header file . . . . 25
   Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 30

1. Introduction ๐ŸŒˆ

1.1. Summary ๐Ÿ’…

okay so, nowadays internet applications that need cryptographic functions at the operating system kernel level usually do it the old way ๐Ÿ™ˆ. The libraries have to be compiled and linked together with the module (driver) that provides the product's functionality ๐Ÿ˜ฉ. So this specification pulls the encryption algorithms out into separate cryptographic modules โœจ. That way they can be developed independently, and you get a solution that's simple, effective, and universal, meaning it works for applications and for kernel-level code ๐Ÿ”ฅ.

This document describes a simple open interface (Crypto API) to external cryptographic libraries ๐Ÿฆ‹. It's optimized for both the application level and the kernel level of the operating system ๐Ÿ‘‘.

1.2. Terminology ๐Ÿ“–

Here's the vocab, bestie ๐Ÿซถ:

  • Cryptoplugin: an operating system unit (driver, shared library, or module) that provides cryptographic functions through a well-defined but OS-specific interface ๐Ÿ”Œ.
  • Cryptolibrary: the part of a cryptoplugin that provides its cryptographic functionality through the Crypto API ๐Ÿง .
  • Wrapper: the part of a cryptoplugin that translates between the Crypto API and the OS-specific interface ๐ŸŽ€.

All the cryptography terms you could ever want are defined in [Schneier] ๐Ÿ“š.

1.3. Objectives of Development ๐ŸŽฏ

The goals of Simple CryptoAPI development are, lowkey, a whole main character list ๐Ÿ‘‘:

  1. To pull the program implementations of encryption, one-way hash function, digital signature, and random number generation algorithms into separate, independently developed modules ๐Ÿงฉ.
  2. To give version independence between the encryption modules and the external cryptoplugin ๐Ÿ”„.
  3. To make sure encrypting algorithm modules can be developed platform-independently, with portable source code ๐ŸŒ.
  4. To let modules be developed independently while still being compatible with each other ๐Ÿค.

2. Cryptoplugin Structure ๐Ÿงšโ€โ™€๏ธ

okay so, to get fast exchange between the cryptoplugin and its client, the cryptoplugin is built as a separate driver (or module) for the particular operating system โšก. See Fig. 1 for how it interacts with its client ๐Ÿ‘€.

                                       Cryptoplugin initialization
                                     / by the operating system
                                     |
                                     |
     +------------------+          +-|-+-------------+
     |                  |          |   |             |
     |  Cryptoplugin's  | -------> |                 |
     |                  |          |  Cryptoplugin   |
     |     client       | <------- |                 |
     |                  |          |   |             |
     +------------------+     |    +---+-------------+
                              |
                              \
                               \ System-dependent CPI

    Fig. 1  Interaction between cryptoplugin and its client

It's made of two parts, shown in Fig. 2 ๐Ÿ’–:

  1. cryptolibrary itself (1)
  2. system-dependent module (wrapper) for interaction between cryptolibrary and its client (2)
     +---------------+-------------------------------+
     |               |                               |
     |              -->       Submodule of           |
     |  Submodule -  |                               |
     |               |   encrypting algorithms (1)   |
     |  wrapper (2)  |                               |
     |              <--       (cryptolibrary)        |
     |               |                               |
     +---------------+-------------------------------+
                     |
                     \
                      \ Cryptographic Program Interface

                Fig. 2  Cryptoplugin structure

The system-dependent module (wrapper) is delivered by the driver-client developer, either as source code or as libraries (for example, as object files) for a particular operating system ๐Ÿ› ๏ธ. The wrapper's job is translating the system-independent application interface into the particular system-dependent interface with the cryptoplugin's client ๐Ÿ”. The wrapper context does not include components that are specific to the cryptoplugin's client functionality or to any cryptographic algorithm ๐Ÿ™…โ€โ™€๏ธ. The interface described in section 3 is the standard for interaction between submodules (1) and (2) ๐Ÿซถ.

A cryptoplugin can contain a number of different algorithms ๐ŸŒธ. It can even contain different implementations of one particular algorithm ๐Ÿ’….

3. Program Interface ๐Ÿฆ‹

The CPI (Cryptographic Program Interface) is a set of functions exported by the encrypting algorithm submodule (cryptolibrary) ๐Ÿ”ฅ. The interface functions are described below, and you can also check Appendix A ๐Ÿ“–.

3.1. Cryptoplugin Initialization Function ๐Ÿš€

This function handles cryptoplugin initialization and gets you info about the algorithms inside the cryptoplugin โœจ. It gets called once, before the cryptoplugin starts operating ๐ŸŽฌ.

   /* CryptoPlugin initialization. Returns pointer to CryptoPluginInfo
   structure on success or NULL on fatal error. */
   CryptoPluginInfo *CryptoPluginInit(
                   void            *param);/* Ptr to OS parameters
                                              (platform-specific) */

Description of parameters ๐ŸŽ€:

  • param - pointer to system-dependent parameters passed to the cryptoplugin by the operating system. The meaning and format of these parameters are specific to each operating system, and they should be described in the documentation for the cryptoplugin wrapper ๐Ÿ“.

The function is called when the cryptoplugin gets initialized ๐ŸŒฑ. If it succeeds, it returns a pointer to a CryptoPluginInfo structure that describes the module and the algorithms implemented in the cryptolibrary ๐ŸŽ‰. If the call doesn't succeed, the function returns NULL, or puts an appropriate error code in the status field of the CryptoPluginInfo structure ๐Ÿ˜ญ. If the initialization only partly succeeds, then the cryptoplugin either returns a CryptoPluginInfo structure transformed so that it contains only the successfully initialized algorithms, or it returns an appropriate error code in the status field of the CryptoAlgInfo structures that describe the reason for the failure ๐Ÿงฉ.

Error codes for the function ๐Ÿ’€:

  • NULL - fatal unsuccessful cryptoplugin initialization. The module is unable even to indicate the reason of failure ๐Ÿ˜ฑ.

The pointer to the cryptoplugin description structure is returned in the case of full or partial success. The status fields in the CryptoPluginInfo structure and in the CryptoAlgInfo structures it contains can be set to these values ๐Ÿ’…:

  • CRYPTO_OK - cryptoplugin (algorithm) is initialized successfully โœ….
  • CRYPTO_ERR_GENERAL - internal error ๐Ÿ™ƒ.
  • CRYPTO_ERR_NOT_SUPPORTED - (only for algorithm) - the algorithm is not supported by the module at the moment ๐Ÿšซ.
  • CRYPTO_ERR_HARDWARE - error of hardware initialization ๐Ÿ”ง.
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources ๐Ÿชซ.
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes that the calling module can release system memory (if it is in a position to do so) and try calling the function once again ๐Ÿง .

3.1.1. Description of CryptoPluginInfo structure ๐ŸŒŸ

The CryptoPluginInfo structure is a fixed-size header that generally describes the cryptoplugin, followed by an array of CryptoAlgInfo structures ๐ŸŽ€. Each CryptoAlgInfo structure describes one particular algorithm implemented in the cryptolibrary (see Appendix A) ๐Ÿ’–.

Structure fields description ๐Ÿ“‹:

  • cpi_version - CPI version (CRYPTO_VER (1,0) is what it should be). The CPI version determines both the function set and the field layout of the CryptoPluginInfo/CryptoAlgInfo structures ๐Ÿ”ข.
  • status - returns the error code if cryptoplugin initialization failed (otherwise it should be CRYPTO_OK) ๐Ÿšฆ.
  • name - text description of the cryptoplugin (ASCII-7 characters only; all unused bytes must be set to 0) ๐Ÿ”ค.
  • version - cryptoplugin version (CRYPTO_VER(maj,min)) ๐Ÿท๏ธ.
  • flags - various flags that characterize the cryptoplugin ๐Ÿณ๏ธ.
  • number_of_algs - number of algorithms the cryptolibrary comprises (i.e. the number of consecutive CryptoAlgInfo structures) ๐ŸŒˆ.

3.1.2. Description of CryptoAlgInfo structure

okay bestie, this is the big one ๐Ÿ’… here's what each field in the CryptoAlgInfo structure is doing:

  • status ๐Ÿšฆ returns the error code if a particular algorithm's initialization failed. Otherwise it should be CRYPTO_OK โœจ
  • id ๐Ÿชช is the algorithm identifier (CRYPTO_A_XXX). Values in the range of 0..249 are reserved. Values in the range of 250..32767 are for algorithms that aren't on the standard list. Algorithm IDs are independent for each algorithm type, but the pairs CRYPTO_TYPE_ENCRYPT and CRYPTO_TYPE_DECRYPT, CRYPTO_TYPE_SIGN and CRYPTO_TYPE_VERIFY, and CRYPTO_TYPE_COMPRESS and CRYPTO_TYPE_UNCOMPRESS are considered equivalent, because each pair does the reverse action of the same nature ๐Ÿ”„
  • group ๐Ÿงฉ is the algorithm implementation group. These are variants of an algorithm with different parameters that the CryptoAlgInfo structure doesn't cover. Values in the range of 0..32767 are well-known numbers defined in Appendix A, and vendors may use values in the range of 32768..65535 however they like ๐ŸŒธ
  • type ๐ŸŽฏ is the algorithm type (CRYPTO_TYPE_XXX). It unambiguously determines what the algorithm is for.
  • version ๐Ÿ”– is the version of the algorithm implementation (CRYPTO_VER(maj,min)).
  • flags ๐Ÿณ๏ธ are the flags that characterize the algorithm and its implementation. All bits that are not defined in Appendix A must be zeroed ๐Ÿงน
  • maxcontexts ๐Ÿ”ข is the maximum number of cryptographic contexts the algorithm implementation can support at the same time. It's 0 if the number is unlimited, or if it's only limited by environmental conditions like memory size ๐Ÿง 
  • name ๐Ÿท๏ธ is the text algorithm name. Only ASCII characters are used, and all unused bytes must be set to 0 ๐Ÿ“

The next fields depend on the algorithm type, so pay attention here, bestie ๐Ÿ‘€

For encryption algorithms (CRYPTO_TYPE_ENCRYPT and CRYPTO_TYPE_DECRYPT):

  • blocklen is the data block length in bytes. The value 1 must be used for stream cipher algorithms ๐ŸŒŠ
  • keylen is the encrypting (or decrypting) key length in bytes ๐Ÿ”‘
  • outlen is the output data size, in bytes, for converting one input data block. It's usually equal to blocklen. When this value can't be predicted, a zero value must be indicated ๐Ÿคทโ€โ™€๏ธ
  • milen is the size of the initialization vector (for block algorithms) or the message indicator (for stream algorithms), in bytes. For block algorithms, a zero value means the algorithm implements ECB encoding. A non-zero milen means the algorithm implements CBC encoding. For stream algorithms, a zero value means the message indicator is not required ๐Ÿ’œ

For signature algorithms (CRYPTO_TYPE_SIGN):

  • blocklen is the block size in bytes. The length of the input signature data will be padded up to this value. When there's no need for padding, the value 1 must be set โœ๏ธ
  • keylen is the private key length in bytes ๐Ÿ”
  • outlen is the signature length in bytes. When this value can't be predicted, a 0 value must be indicated. If the signature consists of several values, the total length is indicated ๐Ÿงฎ
  • milen is the signature parameter length (a random number). A non-zero value specifies that length, and a zero value indicates the parameter is not required ๐ŸŽฒ

For signature verification algorithms (CRYPTO_TYPE_VERIFY):

  • blocklen is not used ๐Ÿ™…โ€โ™€๏ธ
  • keylen is the length of the public key in bytes ๐Ÿ—๏ธ
  • outlen is the signature length in bytes. When this value can't be predicted, a 0 value must be indicated. If the signature consists of several values, the total length is indicated ๐Ÿงพ
  • milen is not used ๐Ÿ™…โ€โ™€๏ธ

For data compression algorithms (CRYPTO_TYPE_COMPRESS):

  • blocklen see outlen ๐Ÿ‘‰
  • keylen is not used ๐Ÿ™…โ€โ™€๏ธ
  • outlen - if the algorithm provides fixed compression with a known value, it's indicated as the blocklen/outlen ratio. The values can be arbitrary. If the compression value isn't known, then outlen is set to 0 and blocklen is not used ๐Ÿ“ฆ
  • milen is not used ๐Ÿ™…โ€โ™€๏ธ

For data uncompressing algorithms (CRYPTO_TYPE_UNCOMPRESS):

  • blocklen see outlen ๐Ÿ‘‰
  • keylen is not used ๐Ÿ™…โ€โ™€๏ธ
  • outlen - if the algorithm provides fixed compression with a known value, it's indicated as the blocklen/outlen ratio. The values can be arbitrary. It's only natural that the ratio will be the reverse of the similar value for the same algorithm of the CRYPTO_TYPE_COMPRESS type. If the compression value isn't known, then outlen is set to 0 and blocklen is not used ๐ŸŽ
  • milen is not used ๐Ÿ™…โ€โ™€๏ธ

For one-way hash function algorithms (CRYPTO_TYPE_HASH):

  • blocklen is the block size in bytes. The length of the input data will be padded up to this value. When there's no need for padding, the value 1 should be used ๐Ÿงฑ
  • keylen is not used ๐Ÿ™…โ€โ™€๏ธ
  • outlen is the resulting hash value length in bytes ๐Ÿซง
  • milen is not used ๐Ÿ™…โ€โ™€๏ธ

For random number generation algorithms (CRYPTO_TYPE_RANDOM):

  • blocklen is not used ๐Ÿ™…โ€โ™€๏ธ
  • keylen is the initial seed length. The value 0 means no seed is required, for example in physical effects based generators ๐ŸŒฑ
  • outlen is the resulting random number length in bytes. The value 0 means arbitrary ๐ŸŽฐ
  • milen is not used ๐Ÿ™…โ€โ™€๏ธ

3.2. Cryptoplugin Deinitialization Function

/* Plugin deinitialization */
CRYPTO_STATUS   CryptoPluginFini(void);

This function gets called before the cryptoplugin operation is terminated ๐Ÿ›‘ Running it closes all open cryptographic contexts, deallocates system resources, and deinitializes the hardware. The value it returns is informational only ๐Ÿ’โ€โ™€๏ธ

Return codes for the function:

  • CRYPTO_OK - the cryptoplugin is deinitialized successfully โœ…
  • CRYPTO_ERR_GENERAL - internal error ๐Ÿ’ฅ
  • CRYPTO_ERR_UNCLOSED_HANDLES - a warning that there were open cryptographic contexts during cryptoplugin deinitialization. The warning is informational only, and the open contexts are destroyed anyway โš ๏ธ

3.3. Cryptographic Context Opening Function

 New algorithm instance (cipher state) */
CRYPTO_STATUS   CryptoOpen(

      CRYPTO_HANDLE   *state, /* Pointer to cipher state
                                 handle (filled on exit) */
      long            algnum, /* Algorithm number in
                                 CryptoPluginInfo structure */
      const char      *key);  /* key (in plain) */

This function creates a cryptographic context copy inside the cryptoplugin and initializes it with the provided key ๐Ÿ” After that, the context's handle gets used in calls to other algorithm functions ๐ŸŽ€

Description of parameters:

  • state - a pointer to the variable that will be set to the handle of the context created, if it succeeded. A NULL parameter value should result in the CRYPTO_ERR_BAD_PARAMS code being returned by the function ๐Ÿซง
  • algnum - the algorithm number in the cryptoplugin. It's equal to the number of the CryptoAlgInfo structure (the one that describes the algorithm) in the CryptoPluginInfo structure. The number begins with a zero value. Keep in mind that it isn't an algorithm identifier, but its number in the cryptoplugin ๐Ÿ”ข
  • key - a pointer to the key (if one is required), or to the seed (for a random number generation algorithm) ๐Ÿ—๏ธ

Notes.

  1. The generated cryptographic context is stored inside the cryptoplugin until it gets destroyed by a call to the CryptoAlgClose function. The maximum number of cryptographic contexts supported by the cryptoplugin can be indicated in the algorithm parameters description. If the maximum number of cryptographic contexts equals zero, then the number of cryptographic contexts is either unlimited (for example, for stateless algorithms like random number generators and one-way hash functions), or it's limited by external factors only (like memory size) ๐Ÿง 

Return codes for the function:

  • CRYPTO_OK - successful completion โœ…
  • CRYPTO_ERR_GENERAL - internal error ๐Ÿ’ฅ
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources ๐Ÿ“‰
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes that the calling module can release system memory (if it's in a position to do so) and try to call the function once again ๐Ÿงน
  • CRYPTO_ERR_BAD_PARAMS - invalid parameters (an invalid algorithm number, or a zero pointer to the handle, or to the key (seed) if it's required) ๐Ÿ™ƒ

3.4. Cryptographic Context Reopening Function

/* Reinitialize algorithm instance */
CRYPTO_STATUS   CryptoReOpen(
                CRYPTO_HANDLE   state, /* current cipher state handle */
                const char      *key);  /* key (in plain) */

This function reinitializes an existing context ๐Ÿ”„ It's used for changing the key without allocating new system resources. The function's parameters are the handle of the previously opened context, and a pointer to a new key ๐Ÿ—๏ธ

Return codes for the function:

  • CRYPTO_OK - successful completion โœ…
  • CRYPTO_ERR_GENERAL - internal error ๐Ÿ’ฅ
  • CRYPTO_ERR_BAD_HANDLE - invalid cryptographic context handle ๐Ÿšซ
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources ๐Ÿ“‰
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes that the calling module may release system memory and try the function call once more ๐Ÿงน
  • CRYPTO_ERR_BAD_PARAMS - invalid parameters (an invalid algorithm number, or a zero pointer to the handle, or to the key (seed) if it's required) ๐Ÿ™ƒ

3.5. Cryptographic Context Closing Function

/* Destroy algorithm instance */
CRYPTO_STATUS   CryptoClose(
                CRYPTO_HANDLE   state); /* Handle of cipher state */

This function destroys a cryptographic context ๐Ÿ’ซ The context's handle is its parameter. The value it returns is informational only ๐Ÿ’โ€โ™€๏ธ

Return codes for the function:

  • CRYPTO_OK - successful completion โœ…
  • CRYPTO_ERR_GENERAL - internal error ๐Ÿ’ฅ
  • CRYPTO_ERR_BAD_HANDLE - invalid cryptographic context handle ๐Ÿšซ

3.6. Key Verification Function

      /* Check key for possible weakness */
      CRYPTO_STATUS   CryptoCheckForWeakKey(
                    long            algnum, /* Algorithm number in
                                    CryptoPluginInfo structure */
                    const char      *key);  /* Proposed key */

This function checks whether key material is weak (from the algorithm's point of view) ๐Ÿ•ต๏ธโ€โ™€๏ธ It's only relevant for encryption/decryption or signing/verification algorithms. The parameters are the algorithm number (similar to CryptoAlgOpen) and a pointer to the key to be verified ๐Ÿ”

Return codes for the function:

  • CRYPTO_O - the key has passed the test ๐ŸŽ‰ (yes, the original says CRYPTO_O here, so I'm keeping it exactly as written ๐Ÿ™ˆ)
  • CRYPTO_ERR_WEAK_KEY - the key has not passed the test, being weak or possibly weak ๐Ÿฅ€
  • CRYPTO_ERR_NOT_SUPPORTED - not supported ๐Ÿ™…โ€โ™€๏ธ
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources ๐Ÿ“‰
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes that the calling module can release system memory (if it's in a position to do so) and try to call the function once again ๐Ÿงน

3.7. Data Transformation Function

okay so this is the big one ๐Ÿ’… the Data Transformation Function, and it's basically the main event. its results and parameters depend on what kind of algorithm you're using ๐Ÿงš

For algorithm types CRYTO_TYPE_ENCRYPT, CRYPTO_TYPE_DECRYPT, CRYPTO_TYPE_SIGN and CRYPTO_TYPE_VERIFY (items 3.7.1 - 3.7.4), the function call results are history independent โœจ same input, same answer, no drama ๐Ÿซถ

/* Perform CryptoTransform (depends on cipher state type) */
CRYPTO_STATUS   CryptoTransform(
                CRYPTO_HANDLE   state,  /* Cipher state */
                const char      *inbuff,/* input data */
                long            inlen,  /* input data length */
                char            *outbuff,/* output buffer */
                long            *outlen,/* On entry - output buffer
                                          length, on exit -  number of
                                          bytes written to outbuff */
                char            *mi);   /* Message indicator  */

Note. okay this is the tea ๐Ÿต stream encryption algorithms might seem like the exception ๐Ÿ™ˆ but nope, the same cryptoalgorithm handle has to hide its history dependence. so from the outside it still looks history independent. iconic behaviour โœจ

For algorithm types CRYPTO_TYPE_COMPRESS, CRYPTO_TYPE_UNCOMPRESS and CRYPTO_TYPE_HASH (items 3.7.5 - 3.7.7), the function calls are history dependent ๐ŸŒˆ the past calls matter here. and for CRYPTO_TYPE_RANDOM, it depends on the implementation: some are history dependent and some aren't, so it's a bit of a mix ๐ŸŽฒ

3.7.1. For CRYPTO_TYPE_ENCRYPT Algorithm Type: ๐Ÿ”

The function encrypts the input data. Its parameters are meant for:

  • inbuff: a pointer to the input data. if this is NULL, the function should return the CRYPTO_ERR_BAD_PARAMS error code ๐Ÿ™…โ€โ™€๏ธ
  • inlen: the input data size in bytes. if the size in the algorithm description is divisible by blocklen, then no padding happens ๐Ÿ’… otherwise the algorithm either pads according to its standard, or returns CRYPTO_ERR_BAD_PARAMS. a zero here is allowed, and the function quits right away with CRYPTO_OK ๐ŸŒธ
  • outbuff: the output data buffer. if this is NULL, then outlen gets set to the output buffer size needed to encrypt the input. in that case you should not get CRYPTO_ERR_SMALL_BUFFER ๐ŸŽ€
  • outlen: the output buffer size goes in as an input, and the number of bytes actually written comes back out as the output. both NULL and zero here give you CRYPTO_ERR_BAD_PARAMS ๐Ÿ’€
  • mi: the message indicator, and what it holds depends on whether the algorithm is block or stream. for block, it's the last block encrypted. when the first block gets encrypted, mi is the initial initialization vector ๐Ÿง for stream, it's the offset of the first byte encrypted in the stream. if the algorithm uses the message indicator and mi is NULL, the function should return CRYPTO_ERR_BAD_PARAMS. if the algorithm doesn't use it (ECB Mode is the example), then NULL is totally fine and any non-NULL value just gets ignored ๐Ÿฆ‹

Returned values:

  • CRYPTO_OK: successful completion โœ…
  • CRYPTO_ERR_GENERAL: internal error
  • CRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handle
  • CRYPTO_ERR_NO_RESOURCES: not enough internal resources
  • CRYPTO_ERR_NO_MEMORY: not enough memory. unlike the general CRYPTO_ERR_NO_RESOURCES, this one assumes the calling module can free up system memory (if it's in a position to) and then try calling the function again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER: the output buffer is too small
  • CRYPTO_ERR_BAD_PARAMS: invalid parameters โŒ

3.7.2. For CRYPTO_TYPE_DECRYPT Algorithm Type: ๐Ÿ”“

The function decrypts the input data. Its parameters are meant for:

  • inbuff: a pointer to the input data. if this is NULL, the function should return CRYPTO_ERR_BAD_PARAMS ๐Ÿ™…โ€โ™€๏ธ
  • inlen: the input data size in bytes. set it to zero and the function quits immediately, returning CRYPTO_OK ๐ŸŒท
  • outbuff: the output data buffer. NULL means outlen gets set to the output buffer size needed to decrypt the input. in that case, no CRYPTO_ERR_SMALL_BUFFER ๐Ÿซง
  • outlen: input is the output buffer size, output is how many bytes got written. NULL and zero both give CRYPTO_ERR_BAD_PARAMS ๐Ÿ’…
  • mi: the message indicator. for block algorithms it's the last block encrypted, and when the first block is decrypted, mi specifies the initial initialization vector ๐Ÿ“ for stream algorithms, it's the offset of the first byte decrypted in the stream. if the algorithm uses mi and it's NULL, the function should return CRYPTO_ERR_BAD_PARAMS. if the algorithm doesn't use it (ECB Mode again), NULL is acceptable and non-NULL values should be ignored ๐Ÿฆ‹

Returned values:

  • CRYPTO_OK: successful completion โœ…
  • CRYPTO_ERR_GENERAL: internal error
  • CRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handle
  • CRYPTO_ERR_NO_RESOURCES: not enough internal resources
  • CRYPTO_ERR_NO_MEMORY: not enough memory. this one assumes the calling module can release system memory (if it's able to) and retry the call, unlike the general CRYPTO_ERR_NO_RESOURCES ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER: the output buffer is too small
  • CRYPTO_ERR_BAD_PARAMS: invalid parameters โŒ

3.7.3. For CRYPTO_TYPE_SIGN Type Algorithm: โœ๏ธ

The function signs the input data. Its parameters are meant for:

  • inbuff: a pointer to the input data. if this is NULL, the function should return the CRYPTO_ERR_BAD_PARAMS code error ๐Ÿ™…โ€โ™€๏ธ
  • inlen: the input data size in bytes. if the size in the algorithm description is divisible by blocklen, no padding gets done. otherwise the algorithm either pads per its standard, or returns CRYPTO_ERR_BAD_PARAMS. zero is allowed, so the function quits at once and returns CRYPTO_OK ๐ŸŒธ
  • outbuff: the output data buffer. NULL means outlen gets set to the output buffer size needed to sign the input, and CRYPTO_ERR_SMALL_BUFFER shouldn't be returned in that case ๐ŸŽ€
  • outlen: input is the output buffer size, output is the number of bytes written. NULL and zero both give CRYPTO_ERR_BAD_PARAMS ๐Ÿ’€
  • mi: a pointer to the signature parameter (usually a random number) if milen in the algorithm description is non-zero. in that case, a zero mi means the algorithm should choose (generate) the parameter itself ๐ŸŽฒ if milen is zero, then mi is ignored ๐Ÿซถ

Returned values:

  • CRYPTO_OK: successful completion โœ…
  • CRYPTO_ERR_GENERAL: internal error
  • CRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handle
  • CRYPTO_ERR_NO_RESOURCES: not enough internal resources
  • CRYPTO_ERR_NO_MEMORY: not enough memory. this one assumes the calling module can free up system memory (if it can) and try the function again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER: the output buffer is too small
  • CRYPTO_ERR_BAD_PARAMS: invalid parameters โŒ

3.7.4. For CRYPTO_TYPE_VERIFY Algorithm Type: ๐Ÿ•ต๏ธโ€โ™€๏ธ

The function verifies the input data's signature. Its parameters are meant for:

  • inbuff: a pointer to the input data. if this is NULL, the function should return the CRYPTO_ERR_BAD_PARAMS code error ๐Ÿ™…โ€โ™€๏ธ
  • inlen: the input data size in bytes. zero is allowed, so the function quits at once and returns CRYPTO_OK ๐ŸŒท
  • outbuff: a pointer to the signature. if this is NULL, the function returns CRYPTO_ERR_BAD_PARAMS. if the signature is made of several parts, they get combined into one array ๐Ÿงฉ
  • outlen: specifies the signature length if the signature length is set to zero in the algorithm description structure. if a non-zero value is in the algorithm description structure, this parameter is ignored. if the signature has several parts, the maximum part length multiplied by the number of parts is specified ๐Ÿฐ
  • mi: not used ๐Ÿ’ค

Returned values:

  • CRYPTO_OK: successful completion โœ…
  • CRYPTO_ERR_INVALID_SIGNATURE: invalid signature ๐Ÿšซ
  • CRYPTO_ERR_GENERAL: internal error
  • CRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handle
  • CRYPTO_ERR_NO_RESOURCES: not enough internal resources
  • CRYPTO_ERR_NO_MEMORY: not enough memory. this one assumes the calling module can release system memory (if it's able to) and call the function again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER: the output buffer is too small
  • CRYPTO_ERR_BAD_PARAMS: invalid parameters โŒ

3.7.5. For CRYPTO_TYPE_COMPRESS Algorithm Type: ๐Ÿ—œ๏ธ

The function compresses the input data. Its parameters are meant for:

  • inbuff: a pointer to the input data ๐Ÿซง
  • inlen: the input data size in bytes. zero is allowed, so the function quits at once and returns CRYPTO_OK ๐ŸŒธ
  • outbuff: the output data buffer. NULL means outlen gets set to the output buffer size needed to compress the input. in that case, no CRYPTO_ERR_SMALL_BUFFER ๐ŸŽ€
  • outlen: input is the output buffer size, output is the number of bytes written. NULL and zero both give CRYPTO_ERR_BAD_PARAMS ๐Ÿ’€
  • mi: not used ๐Ÿ’ค

Returned values:

  • CRYPTO_OK: successful completion โœ…
  • CRYPTO_ERR_GENERAL: internal error
  • CRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handle
  • CRYPTO_ERR_NO_RESOURCES: insufficient internal resources
  • CRYPTO_ERR_NO_MEMORY: not enough memory. this one assumes the calling module can free up system memory (if it can) and try the call again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER: the output buffer is too small
  • CRYPTO_ERR_BAD_PARAMS: invalid parameters โŒ

3.7.6. For CRYPTO_TYPE_UNCOMPRESS Algorithm Type: ๐ŸŽ€

Okay so this one is basically the undo button for compression ๐Ÿงš It decompresses the input data. Its parameters are intended for:

  • inbuff - pointer to the input data.
  • inlen - input data size (in bytes). Zero is allowed, so the function quits right away and returns CRYPTO_OK โœจ
  • outbuff - output data buffer. A NULL value makes outlen get set to the output buffer size needed to decompress the input buffer. In that case CRYPTO_ERR_SMALL_BUFFER should not be returned ๐Ÿ’–
  • outlen - the output buffer size comes in as an input parameter, and the number of bytes written into the output buffer goes back out as the output parameter. Both a NULL value and a zero value result in CRYPTO_ERR_BAD_PARAMS being returned by the function ๐Ÿ™ˆ
  • mi - is not used.

Returned values:

  • CRYPTO_OK - successful completion. ๐Ÿ’…
  • CRYPTO_ERR_GENERAL - internal error.
  • CRYPTO_ERR_BAD_HANDLE - invalid cryptographic context handle.
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources.
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes the calling module can release system memory (if it's in a position to) and try calling the function again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER - insufficient output buffer size.
  • CRYPTO_ERR_BAD_PARAMS - invalid parameters.

3.7.7. For CRYPTO_TYPE_HASH Algorithm Type: ๐ŸŒธ

This is the hash one, and it's giving main character energy ๐Ÿ‘‘ It calculates the hash value of the input data. Its parameters are intended for:

  • inbuff - pointer to the input data. If it's NULL, the function calculates a cumulative hash value for all the data represented so far (counting everything that came before). If the total length of all the data represented by now is divisible by blocklen and outbuff is non-NULL, the result gets returned to outbuff. Nothing is written to outbuff when the length isn't divisible by blocklen. A NULL inbuff marks the last conversion: the input data gets padded up to the blocklen size and the result is written to the outbuff address. The padding procedure is defined by the algorithm. ๐Ÿ”ฅ
  • inlen - input data size (in bytes). Zero is allowed, and the function quits right away and returns CRYPTO_OK.
  • outbuff - output data buffer.
  • outlen - the output buffer size comes in as an input parameter, and the number of bytes written into the output buffer comes out as the output parameter. For an intermediate conversion value (inbuff is not NULL) where the total length of data represented so far is not divisible by blocklen, outlen is set to zero and the hash value is not written to outbuff. Both a NULL value and a zero value result in CRYPTO_ERR_BAD_PARAMS being returned by the function ๐Ÿ™ˆ
  • mi - is not used.

Returned values:

  • CRYPTO_OK - successful completion. โœจ
  • CRYPTO_ERR_GENERAL - internal error.
  • CRYPTO_ERR_BAD_HANDLE - invalid cryptographic context handle.
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources.
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes the calling module can release system memory (if it's in a position to) and try calling the function again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER - insufficient output buffer size.
  • CRYPTO_ERR_BAD_PARAMS - invalid parameters.

3.7.8. For CRYPTO_TYPE_RANDOM Algorithm Type: ๐Ÿฆ‹

The random one! ๐ŸŽฒ It generates a random number. Its parameters are intended for:

  • inbuff - pointer to the input data used for generation (when one of the pseudorandom algorithms is implemented). A NULL parameter means there's no input data.
  • inlen - input data size (in bytes).
  • outbuff - output data.
  • outlen - the output buffer size comes in as an input parameter, and the number of bytes written into the output buffer comes out as the output parameter. If the algorithm description sets the generated number size to zero (meaning arbitrary), then the outlen value decides how many random bytes the calling procedure needs ๐Ÿ“
  • mi - is not used.

Returned values:

  • CRYPTO_OK - successful completion. ๐Ÿ’–
  • CRYPTO_ERR_GENERAL - internal error.
  • CRYPTO_ERR_BAD_HANDLE - invalid cryptographic context handle.
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources.
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes the calling module can release system memory (if it's in a position to) and try calling the function again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER - insufficient output buffer size.
  • CRYPTO_ERR_BAD_PARAMS - invalid parameters.

3.8. Cryptographic Context Control Function ๐ŸŽ€

Here's the control panel, bestie ๐ŸŽ›๏ธ The signature looks like this:

/* Algorithm control */
CRYPTO_STATUS   CryptoControl(
                CRYPTO_HANDLE   state,  /* Cipher state handle */
                long            cmd,    /* Control command */
                long            param,  /* Parameter id */
                char            val,    /* Parameter value */
                long            *len);  /* For CRYPTO_GET: on entry -
                                           val buffer length, on exit -
                                           number of bytes written to
                                           val; for CRYPTO_SET: length
                                           of value to set */

The function manages the internal parameters of a cryptographic context โœจ You can use it to check context parameters or to change the context state. For example, it can tell you about the cryptoalgorithm (like whether the given context is using hardware encryption facilities), or it can "scroll" a stream algorithm's context if that's needed, etc. ๐ŸŒˆ

Description of parameters:

  • state - cryptographic context handle.
  • cmd - command (CRYPTO_GET or CRYPTO_SET).
  • param - identifier of the parameter. Values in the range of 0..32767 are assigned well-known numbers for all algorithms. Values in the range of 32768..65535 mean various variables for various algorithms, and the cryptolibrary developer can use them however they like ๐Ÿงš
  • val - pointer to the data buffer.
  • len - data size (in bytes).

Returned values:

  • CRYPTO_OK - successful completion. ๐Ÿ’…
  • CRYPTO_ERR_GENERAL - internal error.
  • CRYPTO_ERR_BAD_HANDLE - invalid cryptographic context handle.
  • CRYPTO_ERR_NO_RESOURCES - insufficient internal resources.
  • CRYPTO_ERR_NO_MEMORY - not enough memory. Unlike the general CRYPTO_ERR_NO_RESOURCES error, this code assumes the calling module can release system memory (if it's in a position to) and try calling the function again ๐Ÿง 
  • CRYPTO_ERR_SMALL_BUFFER - insufficient output buffer size.
  • CRYPTO_ERR_BAD_PARAMS - invalid parameters.

4. Cryptoplugin Registration Procedure ๐Ÿ”Œ

Okay so the cryptoplugin should be linked together with the cryptoplugin wrapper library. The cryptoplugin's client developer delivers that wrapper library, and the linking follows the rules the module-client developer sets for each platform ๐Ÿ’– The result should be a driver (module) of the appropriate operating system that implements the cryptolibrary functions. The driver should be one of the drivers loaded during operating system boot โœจ

The procedure for installing the cryptoplugin driver should be defined, documented, and automated when necessary. The cryptoplugin developer handles that part ๐Ÿ› ๏ธ At the beginning of operation, the driver-client figures out whether a cryptoplugin driver is available and sets up a connection with it. The module-client configuration and the current security policy together decide which data conversion algorithms get chosen ๐Ÿฆ‹

5. Security Considerations ๐Ÿ”

Security issues are addressed throughout this memo. ๐Ÿ™ˆ Honestly this is the whole plot, so keep an eye on every section!

6. References ๐Ÿ“š

[Schneier] Bruce Schneier, Applied Cryptography - Protocols, Algorithms, and Source Code in C (Second Edition), John Wiley & Sons, Inc., 1996.

[IPsec] Kent, S. and R. Atkinson, "Security Architecture for the Internet Protocol", RFC 2401, November 1998.

[ISAKMP] Maughhan, D., Schertler, M. Schneider, M. and J. Turner, "Internet Security Association and Key Management Protocol (ISAKMP)", RFC 2408, November 1998.

[IKE] Harkins, D. and D. Carrel, "The Internet Key Exchange (IKE)", RFC 2409, November 1998.

[TLS] Dierks, T. and C. Allen, "The TLS protocol Version 1.0", RFC 2246, January 1999.

7. Author's Address ๐Ÿ’Œ

Valery Smyslov
TWS
Centralny prospekt, 11,
Moscow, Russia

Phone: +7 (095) 531 4633
Fax:   +7 (095) 531 2403
EMail: svan@trustworks.com

Appendix A. The interface specification as a C header file ๐Ÿงšโ€โ™€๏ธ

#ifndef __CRYPTPI_H
#define __CRYPTPI_H

#define CRYPTO_VER(maj,min)     (((maj & 0xff) << 8) | (min & 0xff))
#define CRYPTO_MAJ_VER(ver)     ((ver >> 8) & 0xff)
#define CRYPTO_MIN_VER(ver)     (ver & 0xff)

#define CRYPTO_PLUGIN_NAME_LEN  64      /* Must be multiple of 4 to */
#define CRYPTO_ALG_NAME_LEN     32      /* avoid alignment problems */

#ifndef CRYPTO_HANDLE
#define CRYPTO_HANDLE           void*   /* cipher state handle */
#endif

typedef enum tag_CRYPTO_STATUS {
        CRYPTO_OK = 1,                  /* success */
        CRYPTO_ERR_GENERAL,             /* undefined (internal) error */
        CRYPTO_ERR_NOT_SUPPORTED,       /* unsupported */
        CRYPTO_ERR_BAD_HANDLE,          /* invalid handle */
        CRYPTO_ERR_SMALL_BUFFER,        /* insufficient output buffer
                                           size */
        CRYPTO_ERR_WEAK_KEY,            /* key is considered to be weak
                                           (semiweak, pseudoweak) */
        CRYPTO_ERR_NO_RESOURCES,        /* insufficient resources to
                                           perform operation */
        CRYPTO_ERR_NO_MEMORY,           /* insufficient memory to
                                           perform operation */
        CRYPTO_ERR_BAD_PARAMS,          /* invalid parameters */
        CRYPTO_ERR_HARDWARE,            /* hardware error */
        CRYPTO_ERR_INVALID_SIGNATURE,   /* invalid signature */
        CRYPTO_ERR_UNCLOSED_HANDLES     /* unclosed handles exist while
                                           plugin deinitializises */
} CRYPTO_STATUS;

/* CryptoControl commands */
#define CRYPTO_GET                      1       /* get parameter */
#define CRYPTO_SET                      2       /* set parameter */

/* Currently defined algorithm types */
#define CRYPTO_TYPE_ENCRYPT             1
#define CRYPTO_TYPE_DECRYPT             2
#define CRYPTO_TYPE_SIGN                3
#define CRYPTO_TYPE_VERIFY              4
#define CRYPTO_TYPE_COMPRESS            5
#define CRYPTO_TYPE_UNCOMPRESS          6
#define CRYPTO_TYPE_HASH                7
#define CRYPTO_TYPE_RANDOM              8
/* Currently defined algorithm IDs (for types
   CRYPTO_TYPE_ENCRYPT & CRYPTO_TYPE_DECRYPT) */
#define CRYPTO_AE_DUMMY                 1       /* no encryption */
#define CRYPTO_AE_DES                   2       /* DES-CBC */
#define CRYPTO_AE_3DES_EDE              3       /* Triple DES-EDE-CBC */
#define CRYPTO_AE_IDEA                  4       /* IDEA-CBC */
#define CRYPTO_AE_RC2                   5       /* RC2 */
#define CRYPTO_AE_RC4                   6       /* RC4 */
#define CRYPTO_AE_RC5                   7       /* RC5 */
#define CRYPTO_AE_SAFER                 8       /* SAFER */
#define CRYPTO_AE_CAST                  9       /* CAST */
#define CRYPTO_AE_BLOWFISH              10      /* Blowfish */
#define CRYPTO_AE_RSA                   11      /* RSA */
#define CRYPTO_AE_GOST                  12      /* GOST */

/* Currently defined algorithm IDs (for types
   CRYPTO_TYPE_SIGN & CRYPTO_TYPE_VERIFY) */
#define CRYPTO_AS_RSA                   2       /* RSA */
#define CRYPTO_AS_DSA                   3       /* DSA */
#define CRYPTO_AS_GOST                  4       /* GOST */

/* Currently defined algorithm IDs (for types
   CRYPTO_TYPE_COMPRESS & CRYPTO_TYPE_UNCOMPRESS) */
#define CRYPTO_AC_DUMMY                 1       /* no compression */
#define CRYPTO_AC_DEFLATE               2       /* Deflate */
#define CRYPTO_AC_LZS                   3       /* LZS */

/* Currently defined algorithm IDs (for type CRYPTO_TYPE_HASH) */
#define CRYPTO_AH_MD5                   1       /* MD5 */
#define CRYPTO_AH_SHA                   2       /* SHA-1 */
#define CRYPTO_AH_GOST                  3       /* GOST */

/* Currently defined algorithm IDs (for type CRYPTO_TYPE_RANDOM) */
#define         CRYPTO_AR_UNKNOWN       1

/* Currently defined plugin flags */
#define CRYPTO_PLUGIN_HARDWARE          1       /* plugin uses hdw */
/* TBD more */

/* Currently defined algorithm flags */
#define CRYPTO_ALG_HARDWARE             1       /* algorithm implemented
                                                   in hardware */
#define CRYPTO_ALG_MULTITHREADED        2       /* implementation allows
                                                   multithreading */
/* TBD more */
/* Currently defined parameters identifiers for CryptoControl */
#define CRYPTO_PARAM_KEY                1       /* Only for CRYPTO_GET -
                                                   get current key */
/* TBD more */

typedef struct  tag_CryptoAlgInfo {
        long    status;                 /* Algorithm status */
        long    type;                   /* algorithm type (One of
                                           CRYPTO_TYPE_XXX) */
        long    id;                     /* algorithm ID */
        long    group;                  /* algorithm group */
        long    version;                /* algorithm version
                                           (CRYPTO_VER) */
        long    flags;                  /* algorithm flags
                                           (CRYPTO_ALG_XXX) */
        long    maxcontexts;            /* max number of cipher states
                                           supported (0 - any) */
        char    name[CRYPTO_ALG_NAME_LEN];      /* algorithm name */
                          /* CRYPT   SIGN    COMPRESS HASH    RANDOM  */
                          /* DECRYPT VERIFY                           */
        long    blocklen; /* blklen (blklen)  inlen   blklen    -     */
        long    keylen;   /* keylen  keylen     -       -     seedlen */
        long    outlen;   /* outlen (signlen) outlen  hashlen randlen */
        long    milen;    /* milen   (param)    -       -       -     */
} CryptoAlgInfo;

typedef struct  tag_CryptoPluginInfo {
        long    cpi_version;            /* Crypto PI version (currently
                                           CRYPTO_VER(1,0)) */
        long    status;                 /* Plugin status */
        char    name[CRYPTO_PLUGIN_NAME_LEN];   /* plugin text
                                                   description */
        long    version;                /* plugin version
                                           (CRYPTO_VER) */
        long    flags;                  /* plugin flags
                                           (CRYPTO_PLUGIN_XXX) */
        long    number_of_algs;         /* number of AlgInfo structures
                                           followed (min 1) */
        CryptoAlgInfo   algs[1];        /* array of AlgInfo structures
                                           (min 1) */
} CryptoPluginInfo;

#ifdef __cplusplus
extern "C" {
#endif

/* CryptoPlugin initialization. Returns pointer to CryptoPluginInfo
structure on success or NULL on fatal error. */
CryptoPluginInfo *CryptoPluginInit(
                void            *param);/* Ptr to OS parameters
                                           (platform-specific) */

/* Plugin deinitialization */
CRYPTO_STATUS   CryptoPluginFini(void);

/* Get new algorithm instance (cipher state) */
CRYPTO_STATUS   CryptoOpen(
                CRYPTO_HANDLE   *state, /* Pointer to cipher state
                                            handle (filled on exit) */
                 long            algnum, /* Algorithm number in
                                            CryptoPluginInfo structure */
                 const char      *key);  /* key (in plain) */

 /* Reinitialize algorithm instance */
 CRYPTO_STATUS   CryptoReOpen(
                 CRYPTO_HANDLE   state, /* current cipher state handle */
                 const char      *key);  /* key (in plain) */

 /* Destroy algorithm instance */
 CRYPTO_STATUS   CryptoClose(
                 CRYPTO_HANDLE   state); /* Handle of cipher state */

 /* Check key for possible weakness */
 CRYPTO_STATUS   CryptoCheckForWeakKey(
                 long            algnum, /* Algorithm number in
                                            CryptoPluginInfo structure */
                 const char      *key);  /* Proposed key */

 /* Perform CryptoTransform (depends on cipher state type) */
 CRYPTO_STATUS   CryptoTransform(
                 CRYPTO_HANDLE   state,  /* Cipher state handle */
                 const char      *inbuff,/* input data */
                 long            inlen,  /* input data length */
                 char            *outbuff,/* output buffer */
                 long            *outlen,/* On entry - output buffer
                                           length, on exit -  number of
                                           bytes written to outbuff */
                 char            *mi);   /* Message indicator  */

 /* Algorithm control */
 CRYPTO_STATUS   CryptoControl(
                 CRYPTO_HANDLE   state,  /* Cipher state handle */
                 long            cmd,    /* Control command */
                 long            param,  /* Parameter id */
                 char            val,    /* Parameter value */
                 long            *len);  /* For CRYPTO_GET: on entry -

                                            val buffer length, on exit -
                                            number of bytes written to
                                            val; for CRYPTO_SET: length
                                            of value to set */

 #ifdef __cplusplus
 }
 #endif

 #endif  /* __CRYPTPI_H */

Okay bestie, that's the whole header file ๐ŸŽ€ It's giving C structs, plugin IDs, and a bunch of TBD vibes ๐Ÿ™ˆ Every number and name in there is the real deal, so don't go changing anything. โœจ

Okay, this part is legal stuff, so I'm keeping it word-for-word. ๐Ÿซถ

Copyright (C) The Internet Society (1999). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement ๐ŸŒธ

Funding for the RFC Editor function is currently provided by the Internet Society. ๐ŸŒˆ

๐Ÿ“ฆ where this page comes from