RFC 2628
Simple Cryptographic Program Interface (Crypto API)
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 Notice ๐
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 ๐:
- To pull the program implementations of encryption, one-way hash function, digital signature, and random number generation algorithms into separate, independently developed modules ๐งฉ.
- To give version independence between the encryption modules and the external cryptoplugin ๐.
- To make sure encrypting algorithm modules can be developed platform-independently, with portable source code ๐.
- 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 ๐:
- cryptolibrary itself (1)
- 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 generalCRYPTO_ERR_NO_RESOURCESerror, 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 beCRYPTO_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 beCRYPTO_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 pairsCRYPTO_TYPE_ENCRYPTandCRYPTO_TYPE_DECRYPT,CRYPTO_TYPE_SIGNandCRYPTO_TYPE_VERIFY, andCRYPTO_TYPE_COMPRESSandCRYPTO_TYPE_UNCOMPRESSare 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):
blocklenis the data block length in bytes. The value 1 must be used for stream cipher algorithms ๐keylenis the encrypting (or decrypting) key length in bytes ๐outlenis the output data size, in bytes, for converting one input data block. It's usually equal toblocklen. When this value can't be predicted, a zero value must be indicated ๐คทโโ๏ธmilenis 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-zeromilenmeans the algorithm implements CBC encoding. For stream algorithms, a zero value means the message indicator is not required ๐
For signature algorithms (CRYPTO_TYPE_SIGN):
blocklenis 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 โ๏ธkeylenis the private key length in bytes ๐outlenis 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 ๐งฎmilenis 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):
blocklenis not used ๐ โโ๏ธkeylenis the length of the public key in bytes ๐๏ธoutlenis 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 ๐งพmilenis not used ๐ โโ๏ธ
For data compression algorithms (CRYPTO_TYPE_COMPRESS):
blocklenseeoutlen๐keylenis 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, thenoutlenis set to 0 andblocklenis not used ๐ฆmilenis not used ๐ โโ๏ธ
For data uncompressing algorithms (CRYPTO_TYPE_UNCOMPRESS):
blocklenseeoutlen๐keylenis 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 theCRYPTO_TYPE_COMPRESStype. If the compression value isn't known, thenoutlenis set to 0 andblocklenis not used ๐milenis not used ๐ โโ๏ธ
For one-way hash function algorithms (CRYPTO_TYPE_HASH):
blocklenis 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 ๐งฑkeylenis not used ๐ โโ๏ธoutlenis the resulting hash value length in bytes ๐ซงmilenis not used ๐ โโ๏ธ
For random number generation algorithms (CRYPTO_TYPE_RANDOM):
blocklenis not used ๐ โโ๏ธkeylenis the initial seed length. The value 0 means no seed is required, for example in physical effects based generators ๐ฑoutlenis the resulting random number length in bytes. The value 0 means arbitrary ๐ฐmilenis 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 theCRYPTO_ERR_BAD_PARAMScode 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.
- 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 generalCRYPTO_ERR_NO_RESOURCESerror, 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 generalCRYPTO_ERR_NO_RESOURCESerror, 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 saysCRYPTO_Ohere, 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 generalCRYPTO_ERR_NO_RESOURCESerror, 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 theCRYPTO_ERR_BAD_PARAMSerror code ๐ โโ๏ธinlen: the input data size in bytes. if the size in the algorithm description is divisible byblocklen, then no padding happens ๐ otherwise the algorithm either pads according to its standard, or returnsCRYPTO_ERR_BAD_PARAMS. a zero here is allowed, and the function quits right away withCRYPTO_OK๐ธoutbuff: the output data buffer. if this is NULL, thenoutlengets set to the output buffer size needed to encrypt the input. in that case you should not getCRYPTO_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 youCRYPTO_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,miis 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 andmiis NULL, the function should returnCRYPTO_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 errorCRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handleCRYPTO_ERR_NO_RESOURCES: not enough internal resourcesCRYPTO_ERR_NO_MEMORY: not enough memory. unlike the generalCRYPTO_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 smallCRYPTO_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 returnCRYPTO_ERR_BAD_PARAMS๐ โโ๏ธinlen: the input data size in bytes. set it to zero and the function quits immediately, returningCRYPTO_OK๐ทoutbuff: the output data buffer. NULL meansoutlengets set to the output buffer size needed to decrypt the input. in that case, noCRYPTO_ERR_SMALL_BUFFER๐ซงoutlen: input is the output buffer size, output is how many bytes got written. NULL and zero both giveCRYPTO_ERR_BAD_PARAMS๐mi: the message indicator. for block algorithms it's the last block encrypted, and when the first block is decrypted,mispecifies the initial initialization vector ๐ for stream algorithms, it's the offset of the first byte decrypted in the stream. if the algorithm usesmiand it's NULL, the function should returnCRYPTO_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 errorCRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handleCRYPTO_ERR_NO_RESOURCES: not enough internal resourcesCRYPTO_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 generalCRYPTO_ERR_NO_RESOURCES๐งCRYPTO_ERR_SMALL_BUFFER: the output buffer is too smallCRYPTO_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 theCRYPTO_ERR_BAD_PARAMScode error ๐ โโ๏ธinlen: the input data size in bytes. if the size in the algorithm description is divisible byblocklen, no padding gets done. otherwise the algorithm either pads per its standard, or returnsCRYPTO_ERR_BAD_PARAMS. zero is allowed, so the function quits at once and returnsCRYPTO_OK๐ธoutbuff: the output data buffer. NULL meansoutlengets set to the output buffer size needed to sign the input, andCRYPTO_ERR_SMALL_BUFFERshouldn't be returned in that case ๐outlen: input is the output buffer size, output is the number of bytes written. NULL and zero both giveCRYPTO_ERR_BAD_PARAMS๐mi: a pointer to the signature parameter (usually a random number) ifmilenin the algorithm description is non-zero. in that case, a zeromimeans the algorithm should choose (generate) the parameter itself ๐ฒ ifmilenis zero, thenmiis ignored ๐ซถ
Returned values:
CRYPTO_OK: successful completion โCRYPTO_ERR_GENERAL: internal errorCRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handleCRYPTO_ERR_NO_RESOURCES: not enough internal resourcesCRYPTO_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 smallCRYPTO_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 theCRYPTO_ERR_BAD_PARAMScode error ๐ โโ๏ธinlen: the input data size in bytes. zero is allowed, so the function quits at once and returnsCRYPTO_OK๐ทoutbuff: a pointer to the signature. if this is NULL, the function returnsCRYPTO_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 errorCRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handleCRYPTO_ERR_NO_RESOURCES: not enough internal resourcesCRYPTO_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 smallCRYPTO_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 returnsCRYPTO_OK๐ธoutbuff: the output data buffer. NULL meansoutlengets set to the output buffer size needed to compress the input. in that case, noCRYPTO_ERR_SMALL_BUFFER๐outlen: input is the output buffer size, output is the number of bytes written. NULL and zero both giveCRYPTO_ERR_BAD_PARAMS๐mi: not used ๐ค
Returned values:
CRYPTO_OK: successful completion โCRYPTO_ERR_GENERAL: internal errorCRYPTO_ERR_BAD_HANDLE: invalid cryptographic context handleCRYPTO_ERR_NO_RESOURCES: insufficient internal resourcesCRYPTO_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 smallCRYPTO_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 returnsCRYPTO_OKโจoutbuff- output data buffer. ANULLvalue makesoutlenget set to the output buffer size needed to decompress the input buffer. In that caseCRYPTO_ERR_SMALL_BUFFERshould 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 aNULLvalue and a zero value result inCRYPTO_ERR_BAD_PARAMSbeing 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 generalCRYPTO_ERR_NO_RESOURCESerror, 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'sNULL, 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 byblocklenandoutbuffis non-NULL, the result gets returned tooutbuff. Nothing is written tooutbuffwhen the length isn't divisible byblocklen. ANULLinbuffmarks the last conversion: the input data gets padded up to theblocklensize and the result is written to theoutbuffaddress. The padding procedure is defined by the algorithm. ๐ฅinlen- input data size (in bytes). Zero is allowed, and the function quits right away and returnsCRYPTO_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 (inbuffis notNULL) where the total length of data represented so far is not divisible byblocklen,outlenis set to zero and the hash value is not written tooutbuff. Both aNULLvalue and a zero value result inCRYPTO_ERR_BAD_PARAMSbeing 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 generalCRYPTO_ERR_NO_RESOURCESerror, 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). ANULLparameter 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 theoutlenvalue 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 generalCRYPTO_ERR_NO_RESOURCESerror, 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_GETorCRYPTO_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 generalCRYPTO_ERR_NO_RESOURCESerror, 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. โจ
Full Copyright Statement ๐
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
- ietf: rfc2628 1999-06
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms