6.12. Cryptographic Functions

Underneath the high-level functions described earlier, cryptographic operations are happening. If you need to access these cryptographic primitives directly, this section describes the functions available.

Most cryptographic operations need keying material, and cryptographic keys have been isolated into it's own data structure Shishi_key. The following illustrates it's contents, but note that you cannot access it's elements directly but must use the accessor functions described below.

struct Shishi_key
{
  int type;    /* RFC 1510 encryption integer type */
  char *value; /* Cryptographic key data */
  int version; /* RFC 1510 ``kvno'' */
};

All functions that operate on this data structure are described now.

const char * shishi_key_principal (Shishi_key * key) key: structure that holds key information

Return value: Returns the principal owning the key. (Not a copy of it, so don't modify or deallocate it.)

void shishi_key_principal_set (Shishi_key * key, const char * principal) key: structure that holds key information

principal: string with new principal name.

Set the principal owning the key. The string is copied into the key, so you can dispose of the variable immediately after calling this function.

const char * shishi_key_realm (Shishi_key * key) key: structure that holds key information

Return value: Returns the realm for the principal owning the key. (Not a copy of it, so don't modify or deallocate it.)

void shishi_key_realm_set (Shishi_key * key, const char * realm) key: structure that holds key information

realm: string with new realm name.

Set the realm for the principal owning the key. The string is copied into the key, so you can dispose of the variable immediately after calling this function.

int shishi_key_type (Shishi_key * key) key: structure that holds key information

Return value: Returns the type of key as an integer as described in the standard.

void shishi_key_type_set (Shishi_key * key, int32_t type) key: structure that holds key information

type: type to set in key.

Set the type of key in key structure.

char * shishi_key_value (Shishi_key * key) key: structure that holds key information

Return value: Returns the key value as a pointer which is valid throughout the lifetime of the key structure.

void shishi_key_value_set (Shishi_key * key, const char * value) key: structure that holds key information

value: input array with key data.

Set the key value and length in key structure.

int shishi_key_version (Shishi_key * key) key: structure that holds key information

Return value: Returns the version of key ("kvno").

void shishi_key_version_set (Shishi_key * key, int version) key: structure that holds key information

version: new version integer.

Set the version of key ("kvno") in key structure.

const char * shishi_key_name (Shishi_key * key) key: structure that holds key information

Calls shishi_cipher_name for key type.

Return value: Return name of key.

size_t shishi_key_length (Shishi_key * key) key: structure that holds key information

Calls shishi_cipher_keylen for key type.

Return value: Returns the length of the key value.

int shishi_key (Shishi * handle, Shishi_key ** key) handle: Shishi library handle create by shishi_init().

key: pointer to structure that will hold newly created key information

Create a new Key information structure.

Return value: Returns SHISHI_OK iff successful.

void shishi_key_done (Shishi_key * key) key: pointer to structure that holds key information.

Deallocates key information structure.

void shishi_key_copy (Shishi_key * dstkey, Shishi_key * srckey) dstkey: structure that holds destination key information

srckey: structure that holds source key information

Copies source key into existing allocated destination key.

int shishi_key_from_value (Shishi * handle, int32_t type, const char * value, Shishi_key ** key) handle: Shishi library handle create by shishi_init().

type: type of key.

value: input array with key value, or NULL.

key: pointer to structure that will hold newly created key information

Create a new Key information structure, and set the key type and key value. KEY contains a newly allocated structure only if this function is successful.

Return value: Returns SHISHI_OK iff successful.

int shishi_key_from_base64 (Shishi * handle, int32_t type, const char * value, Shishi_key ** key) handle: Shishi library handle create by shishi_init().

type: type of key.

value: input string with base64 encoded key value, or NULL.

key: pointer to structure that will hold newly created key information

Create a new Key information structure, and set the key type and key value. KEY contains a newly allocated structure only if this function is successful.

Return value: Returns SHISHI_INVALID_KEY if the base64 encoded key length doesn't match the key type, and SHISHI_OK on success.

int shishi_key_random (Shishi * handle, int32_t type, Shishi_key ** key) handle: Shishi library handle create by shishi_init().

type: type of key.

key: pointer to structure that will hold newly created key information

Create a new Key information structure for the key type and some random data. KEY contains a newly allocated structure only if this function is successful.

Return value: Returns SHISHI_OK iff successful.

int shishi_key_from_random (Shishi * handle, int32_t type, const char * random, size_t randomlen, Shishi_key ** outkey) handle: Shishi library handle create by shishi_init().

type: type of key.

random: random data.

randomlen: length of random data.

outkey: pointer to structure that will hold newly created key information

Create a new Key information structure, and set the key type and key value using shishi_random_to_key(). KEY contains a newly allocated structure only if this function is successful.

Return value: Returns SHISHI_OK iff successful.

int shishi_key_from_string (Shishi * handle, int32_t type, const char * password, size_t passwordlen, const char * salt, size_t saltlen, const char * parameter, Shishi_key ** outkey) handle: Shishi library handle create by shishi_init().

type: type of key.

password: input array containing password.

passwordlen: length of input array containing password.

salt: input array containing salt.

saltlen: length of input array containing salt.

parameter: input array with opaque encryption type specific information.

outkey: pointer to structure that will hold newly created key information

Create a new Key information structure, and set the key type and key value using shishi_string_to_key(). KEY contains a newly allocated structure only if this function is successful.

Return value: Returns SHISHI_OK iff successful.

Applications that run uninteractively may need keying material. In these cases, the keys are stored in a file, a file that is normally stored on the local host. The file should be protected from unauthorized access. The file is in ASCII format and contains keys as outputed by shishi_key_print. All functions that handle these keys sets are described now.

Shishi_key * shishi_keys_for_serverrealm_in_file (Shishi * handle, const char * filename, const char * server, const char * realm) handle: Shishi library handle create by shishi_init().

filename: file to read keys from.

server: server name to get key for.

realm: realm of server to get key for.

Return value: Returns the key for specific server and realm, read from the indicated file, or NULL if no key could be found or an error encountered.

Shishi_key * shishi_keys_for_server_in_file (Shishi * handle, const char * filename, const char * server) handle: Shishi library handle create by shishi_init().

filename: file to read keys from.

server: server name to get key for.

Return value: Returns the key for specific server, read from the indicated file, or NULL if no key could be found or an error encountered.

Shishi_key * shishi_keys_for_localservicerealm_in_file (Shishi * handle, const char * filename, const char * service, const char * realm) handle: Shishi library handle create by shishi_init().

filename: file to read keys from.

service: service to get key for.

realm: realm of server to get key for, or NULL for default realm.

Return value: Returns the key for the server "SERVICE/HOSTNAMEREALM" (where HOSTNAME is the current system's hostname), read from the default host keys file (see shishi_hostkeys_default_file()), or NULL if no key could be found or an error encountered.

The previous functions require that the filename is known. For some applications, servers, it makes sense to provide a system default. These key sets used by server applications are known as "hostkeys". Here are the functions that operate on hostkeys (they are mostly wrappers around generic key sets).

const char * shishi_hostkeys_default_file (Shishi * handle) handle: Shishi library handle create by shishi_init().

Return value: Returns the default host key filename used in the library. (Not a copy of it, so don't modify or deallocate it.)

void shishi_hostkeys_default_file_set (Shishi * handle, const char * hostkeysfile) handle: Shishi library handle create by shishi_init().

hostkeysfile: string with new default hostkeys file name, or NULL to reset to default.

Set the default host key filename used in the library. The string is copied into the library, so you can dispose of the variable immediately after calling this function.

Shishi_key * shishi_hostkeys_for_server (Shishi * handle, const char * server) handle: Shishi library handle create by shishi_init().

server: server name to get key for

Return value: Returns the key for specific server, read from the default host keys file (see shishi_hostkeys_default_file()), or NULL if no key could be found or an error encountered.

Shishi_key * shishi_hostkeys_for_serverrealm (Shishi * handle, const char * server, const char * realm) handle: Shishi library handle create by shishi_init().

server: server name to get key for

realm: realm of server to get key for.

Return value: Returns the key for specific server and realm, read from the default host keys file (see shishi_hostkeys_default_file()), or NULL if no key could be found or an error encountered.

Shishi_key * shishi_hostkeys_for_localservicerealm (Shishi * handle, const char * service, const char * realm) handle: Shishi library handle create by shishi_init().

service: service to get key for.

realm: realm of server to get key for, or NULL for default realm.

Return value: Returns the key for the server "SERVICE/HOSTNAMEREALM" (where HOSTNAME is the current system's hostname), read from the default host keys file (see shishi_hostkeys_default_file()), or NULL if no key could be found or an error encountered.

Shishi_key * shishi_hostkeys_for_localservice (Shishi * handle, const char * service) handle: Shishi library handle create by shishi_init().

service: service to get key for.

Return value: Returns the key for the server "SERVICE/HOSTNAME" (where HOSTNAME is the current system's hostname), read from the default host keys file (see shishi_hostkeys_default_file()), or NULL if no key could be found or an error encountered.

After creating the key structure, it can be used to encrypt and decrypt data, calculate checksum on data etc. All available functions are described now.

int shishi_cipher_supported_p (int32_t type) type: encryption type, see Shishi_etype.

Return value: Return 0 iff cipher is unsupported.

const char * shishi_cipher_name (int32_t type) type: encryption type, see Shishi_etype.

Return value: Return name of encryption type, e.g. "des3-cbc-sha1-kd", as defined in the standards.

int shishi_cipher_blocksize (int32_t type) type: encryption type, see Shishi_etype.

Return value: Return block size for encryption type, as defined in the standards.

int shishi_cipher_confoundersize (int32_t type) type: encryption type, see Shishi_etype.

Return value: Returns the size of the confounder (random data) for encryption type, as defined in the standards.

size_t shishi_cipher_keylen (int32_t type) type: encryption type, see Shishi_etype.

Return value: Return length of key used for the encryption type, as defined in the standards.

size_t shishi_cipher_randomlen (int32_t type) type: encryption type, see Shishi_etype.

Return value: Return length of random used for the encryption type, as defined in the standards.

int shishi_cipher_defaultcksumtype (int32_t type) type: encryption type, see Shishi_etype.

Return value: Return associated checksum mechanism for the encryption type, as defined in the standards.

int shishi_cipher_parse (const char * cipher) cipher: name of encryption type, e.g. "des3-cbc-sha1-kd".

Return value: Return encryption type corresponding to a string.

int shishi_checksum_supported_p (int32_t type) type: checksum type, see Shishi_cksumtype.

Return value: Return 0 iff checksum is unsupported.

const char * shishi_checksum_name (int32_t type) type: checksum type, see Shishi_cksumtype.

Return value: Return name of checksum type, e.g. "hmac-sha1-96-aes256", as defined in the standards.

size_t shishi_checksum_cksumlen (int32_t type) type: checksum type, see Shishi_cksumtype.

Return value: Return length of checksum used for the checksum type, as defined in the standards.

int shishi_checksum_parse (const char * checksum) checksum: name of checksum type, e.g. "hmac-sha1-96-aes256".

Return value: Return checksum type, see Shishi_cksumtype, corresponding to a string.

int shishi_string_to_key (Shishi * handle, int32_t keytype, const char * password, size_t passwordlen, const char * salt, size_t saltlen, const char * parameter, Shishi_key * outkey) handle: shishi handle as allocated by shishi_init().

keytype: cryptographic encryption type, see Shishi_etype.

password: input array with password.

passwordlen: length of input array with password.

salt: input array with salt.

saltlen: length of input array with salt.

parameter: input array with opaque encryption type specific information.

outkey: allocated key handle that will contain new key.

Derive key from a string (password) and salt (commonly concatenation of realm and principal) for specified key type, and set the type and value in the given key to the computed values. The parameter value is specific for each keytype, and can be set if the parameter information is not available.

Return value: Returns SHISHI_OK iff successful.

int shishi_random_to_key (Shishi * handle, int32_t keytype, char * random, size_t randomlen, Shishi_key * outkey) handle: shishi handle as allocated by shishi_init().

keytype: cryptographic encryption type, see Shishi_etype.

random: input array with random data.

randomlen: length of input array with random data.

outkey: allocated key handle that will contain new key.

Derive key from random data for specified key type, and set the type and value in the given key to the computed values.

Return value: Returns SHISHI_OK iff successful.

int shishi_checksum (Shishi * handle, Shishi_key * key, int keyusage, int cksumtype, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to compute checksum with.

keyusage: integer specifying what this key is used for.

cksumtype: the checksum algorithm to use.

in: input array with data to integrity protect.

inlen: size of input array with data to integrity protect.

out: output array with newly allocated integrity protected data.

outlen: output variable with length of output array with checksum.

Integrity protect data using key, possibly altered by supplied key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_verify (Shishi * handle, Shishi_key * key, int keyusage, int cksumtype, const char * in, size_t inlen, const char * cksum, size_t cksumlen) handle: shishi handle as allocated by shishi_init().

key: key to verify checksum with.

keyusage: integer specifying what this key is used for.

cksumtype: the checksum algorithm to use.

in: input array with data that was integrity protected.

inlen: size of input array with data that was integrity protected.

cksum: input array with alleged checksum of data.

cksumlen: size of input array with alleged checksum of data.

Verify checksum of data using key, possibly altered by supplied key usage. If key usage is 0, no key derivation is used.

Return value: Returns SHISHI_OK iff successful.

int shishi_encrypt_ivupdate_etype (Shishi * handle, Shishi_key * key, int keyusage, int32_t etype, const char * iv, size_t ivlen, char ** ivout, size_t * ivoutlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to encrypt with.

keyusage: integer specifying what this key is encrypting.

etype: integer specifying what cipher to use.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

ivout: output array with newly allocated updated initialization vector.

ivoutlen: size of output array with updated initialization vector.

in: input array with data to encrypt.

inlen: size of input array with data to encrypt.

out: output array with newly allocated encrypted data.

outlen: output variable with size of newly allocated output array.

Encrypts data as per encryption method using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. If IVOUT or IVOUTLEN is NULL, the updated IV is not saved anywhere.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_encrypt_iv_etype (Shishi * handle, Shishi_key * key, int keyusage, int32_t etype, const char * iv, size_t ivlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to encrypt with.

keyusage: integer specifying what this key is encrypting.

etype: integer specifying what cipher to use.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

in: input array with data to encrypt.

inlen: size of input array with data to encrypt.

out: output array with newly allocated encrypted data.

outlen: output variable with size of newly allocated output array.

Encrypts data as per encryption method using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The next IV is lost, see shishi_encrypt_ivupdate_etype if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_encrypt_etype (Shishi * handle, Shishi_key * key, int keyusage, int32_t etype, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to encrypt with.

keyusage: integer specifying what this key is encrypting.

etype: integer specifying what cipher to use.

in: input array with data to encrypt.

inlen: size of input array with data to encrypt.

out: output array with newly allocated encrypted data.

outlen: output variable with size of newly allocated output array.

Encrypts data as per encryption method using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The default IV is used, see shishi_encrypt_iv_etype if you need to alter it. The next IV is lost, see shishi_encrypt_ivupdate_etype if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_encrypt_ivupdate (Shishi * handle, Shishi_key * key, int keyusage, const char * iv, size_t ivlen, char ** ivout, size_t * ivoutlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to encrypt with.

keyusage: integer specifying what this key is encrypting.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

ivout: output array with newly allocated updated initialization vector.

ivoutlen: size of output array with updated initialization vector.

in: input array with data to encrypt.

inlen: size of input array with data to encrypt.

out: output array with newly allocated encrypted data.

outlen: output variable with size of newly allocated output array.

Encrypts data using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. If IVOUT or IVOUTLEN is NULL, the updated IV is not saved anywhere.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_encrypt_iv (Shishi * handle, Shishi_key * key, int keyusage, const char * iv, size_t ivlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to encrypt with.

keyusage: integer specifying what this key is encrypting.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

in: input array with data to encrypt.

inlen: size of input array with data to encrypt.

out: output array with newly allocated encrypted data.

outlen: output variable with size of newly allocated output array.

Encrypts data using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The next IV is lost, see shishi_encrypt_ivupdate if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_encrypt (Shishi * handle, Shishi_key * key, int keyusage, char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to encrypt with.

keyusage: integer specifying what this key is encrypting.

in: input array with data to encrypt.

inlen: size of input array with data to encrypt.

out: output array with newly allocated encrypted data.

outlen: output variable with size of newly allocated output array.

Encrypts data using specified key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The default IV is used, see shishi_encrypt_iv if you need to alter it. The next IV is lost, see shishi_encrypt_ivupdate if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_decrypt_ivupdate_etype (Shishi * handle, Shishi_key * key, int keyusage, int32_t etype, const char * iv, size_t ivlen, char ** ivout, size_t * ivoutlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to decrypt with.

keyusage: integer specifying what this key is decrypting.

etype: integer specifying what cipher to use.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

ivout: output array with newly allocated updated initialization vector.

ivoutlen: size of output array with updated initialization vector.

in: input array with data to decrypt.

inlen: size of input array with data to decrypt.

out: output array with newly allocated decrypted data.

outlen: output variable with size of newly allocated output array.

Decrypts data as per encryption method using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. If IVOUT or IVOUTLEN is NULL, the updated IV is not saved anywhere.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_decrypt_iv_etype (Shishi * handle, Shishi_key * key, int keyusage, int32_t etype, const char * iv, size_t ivlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to decrypt with.

keyusage: integer specifying what this key is decrypting.

etype: integer specifying what cipher to use.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

in: input array with data to decrypt.

inlen: size of input array with data to decrypt.

out: output array with newly allocated decrypted data.

outlen: output variable with size of newly allocated output array.

Decrypts data as per encryption method using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The next IV is lost, see shishi_decrypt_ivupdate_etype if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_decrypt_etype (Shishi * handle, Shishi_key * key, int keyusage, int32_t etype, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to decrypt with.

keyusage: integer specifying what this key is decrypting.

etype: integer specifying what cipher to use.

in: input array with data to decrypt.

inlen: size of input array with data to decrypt.

out: output array with newly allocated decrypted data.

outlen: output variable with size of newly allocated output array.

Decrypts data as per encryption method using specified key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The default IV is used, see shishi_decrypt_iv_etype if you need to alter it. The next IV is lost, see shishi_decrypt_ivupdate_etype if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_decrypt_ivupdate (Shishi * handle, Shishi_key * key, int keyusage, const char * iv, size_t ivlen, char ** ivout, size_t * ivoutlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to decrypt with.

keyusage: integer specifying what this key is decrypting.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

ivout: output array with newly allocated updated initialization vector.

ivoutlen: size of output array with updated initialization vector.

in: input array with data to decrypt.

inlen: size of input array with data to decrypt.

out: output array with newly allocated decrypted data.

outlen: output variable with size of newly allocated output array.

Decrypts data using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. If IVOUT or IVOUTLEN is NULL, the updated IV is not saved anywhere.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_decrypt_iv (Shishi * handle, Shishi_key * key, int keyusage, const char * iv, size_t ivlen, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to decrypt with.

keyusage: integer specifying what this key is decrypting.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

in: input array with data to decrypt.

inlen: size of input array with data to decrypt.

out: output array with newly allocated decrypted data.

outlen: output variable with size of newly allocated output array.

Decrypts data using specified initialization vector and key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The next IV is lost, see shishi_decrypt_ivupdate_etype if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_decrypt (Shishi * handle, Shishi_key * key, int keyusage, const char * in, size_t inlen, char ** out, size_t * outlen) handle: shishi handle as allocated by shishi_init().

key: key to decrypt with.

keyusage: integer specifying what this key is decrypting.

in: input array with data to decrypt.

inlen: size of input array with data to decrypt.

out: output array with newly allocated decrypted data.

outlen: output variable with size of newly allocated output array.

Decrypts data specified key. The key actually used is derived using the key usage. If key usage is 0, no key derivation is used. The OUT buffer must be deallocated by the caller. The default IV is used, see shishi_decrypt_iv if you need to alter it. The next IV is lost, see shishi_decrypt_ivupdate if you need it.

Note that DECRYPT(ENCRYPT(data)) does not necessarily yield data exactly, some Kerberos encryption types add pad to make the data fit into the block size of the encryption algorithm. Furthermore, the pad is not guaranteed to look in any special way, although existing implementations often pad with the zero byte. This means that you may have to "frame" data, so it is possible to infer the original length after decryption. Compare ASN.1 DER which contains such information.

Return value: Returns SHISHI_OK iff successful.

int shishi_n_fold (Shishi * handle, const char * in, size_t inlen, char * out, size_t outlen) handle: shishi handle as allocated by shishi_init().

in: input array with data to decrypt.

inlen: size of input array with data to decrypt ("M").

out: output array with decrypted data.

outlen: size of output array ("N").

Fold data into a fixed length output array, with the intent to give each input bit approximately equal weight in determining the value of each output bit.

The algorithm is from "A Better Key Schedule For DES-like Ciphers" by Uri Blumenthal and Steven M. Bellovin, <URL:http://www.research.att.com/~smb/papers/ides.pdf>, although the sample vectors provided by the paper are incorrect.

Return value: Returns SHISHI_OK iff successful.

int shishi_dr (Shishi * handle, Shishi_key * key, const char * constant, size_t constantlen, char * derivedrandom, size_t derivedrandomlen) handle: shishi handle as allocated by shishi_init().

key: input array with cryptographic key to use.

constant: input array with the constant string.

constantlen: size of input array with the constant string.

derivedrandom: output array with derived random data.

derivedrandomlen: size of output array with derived random data.

Derive "random" data from a key and a constant thusly: DR(KEY, CONSTANT) = TRUNCATE(DERIVEDRANDOMLEN, SHISHI_ENCRYPT(KEY, CONSTANT)).

Return value: Returns SHISHI_OK iff successful.

int shishi_dk (Shishi * handle, Shishi_key * key, const char * constant, size_t constantlen, Shishi_key * derivedkey) handle: shishi handle as allocated by shishi_init().

key: input cryptographic key to use.

constant: input array with the constant string.

constantlen: size of input array with the constant string.

derivedkey: pointer to derived key (allocated by caller).

Derive a key from a key and a constant thusly: DK(KEY, CONSTANT) = SHISHI_RANDOM-TO-KEY(SHISHI_DR(KEY, CONSTANT)).

Return value: Returns SHISHI_OK iff successful.

int shishi_pbkdf2_sha1 (Shishi * handle, const char * P, size_t Plen, const char * S, size_t Slen, unsigned int c, unsigned int dkLen, char * DK) handle: shishi handle as allocated by shishi_init().

P: input password, an octet string

Plen: length of password, an octet string

S: input salt, an octet string

Slen: length of salt, an octet string

c: iteration count, a positive integer

dkLen: intended length in octets of the derived key, a positive integer, at most (2^32 - 1) * hLen. The DK array must have room for this many characters.

DK: output derived key, a dkLen-octet string

Derive key using the PBKDF2 defined in PKCS5. PBKDF2 applies a pseudorandom function to derive keys. The length of the derived key is essentially unbounded. (However, the maximum effective search space for the derived key may be limited by the structure of the underlying pseudorandom function, which is this function is always SHA1.)

Return value: Returns SHISHI_OK iff successful.

An easier way to use encryption and decryption if your application repeatedly calls, e.g., shishi_encrypt_ivupdate, is to use the following functions. They store the key, initialization vector, etc, in a context, and the encryption and decryption operations update the IV within the context automatically.

Shishi_crypto * shishi_crypto (Shishi * handle, Shishi_key * key, int keyusage, int32_t etype, const char * iv, size_t ivlen) handle: shishi handle as allocated by shishi_init().

key: key to encrypt with.

keyusage: integer specifying what this key will encrypt/decrypt.

etype: integer specifying what cipher to use.

iv: input array with initialization vector

ivlen: size of input array with initialization vector.

Initialize a crypto context. This store a key, keyusage, encryption type and initialization vector in a "context", and the caller can then use this context to perform encryption via shishi_crypto_encrypt() and decryption via shishi_crypto_encrypt() without supplying all those details again. The functions also takes care of propagating the IV between calls.

When the application no longer need to use the context, it should deallocate resources associated with it by calling shishi_crypto_done().

Return value: Return a newly allocated crypto context.

int shishi_crypto_encrypt (Shishi_crypto * ctx, const char * in, size_t inlen, char ** out, size_t * outlen) ctx: crypto context as returned by shishi_crypto().

in: input array with data to encrypt.

inlen: size of input array with data to encrypt.

out: output array with newly allocated encrypted data.

outlen: output variable with size of newly allocated output array.

Encrypt data, using information (e.g., key and initialization vector) from context. The IV is updated inside the context after this call.

When the application no longer need to use the context, it should deallocate resources associated with it by calling shishi_crypto_done().

Return value: Returns SHISHI_OK iff successful.

int shishi_crypto_decrypt (Shishi_crypto * ctx, const char * in, size_t inlen, char ** out, size_t * outlen) ctx: crypto context as returned by shishi_crypto().

in: input array with data to decrypt.

inlen: size of input array with data to decrypt.

out: output array with newly allocated decrypted data.

outlen: output variable with size of newly allocated output array.

Decrypt data, using information (e.g., key and initialization vector) from context. The IV is updated inside the context after this call.

When the application no longer need to use the context, it should deallocate resources associated with it by calling shishi_crypto_done().

Return value: Returns SHISHI_OK iff successful.

void shishi_crypto_close (Shishi_crypto * ctx) ctx: crypto context as returned by shishi_crypto().

Deallocate resources associated with the crypto context.

Also included in Shishi is an interface to the really low-level cryptographic primitives. They map directly on the underlying cryptographic library used (e.g., Nettle) and is used internally by Shishi.

int shishi_randomize (Shishi * handle, int strong, char * data, size_t datalen) handle: shishi handle as allocated by shishi_init().

strong: 0 iff operation should not block, non-0 for very strong randomness.

data: output array to be filled with random data.

datalen: size of output array.

Store cryptographically random data of given size in the provided buffer.

Return value: Returns SHISHI_OK iff successful.

int shishi_crc (Shishi * handle, const char * in, size_t inlen, char * out[4]) handle: shishi handle as allocated by shishi_init().

in: input character array of data to checksum.

inlen: length of input character array of data to checksum.

Compute checksum of data using CRC32 modified according to RFC 1510. The out buffer must be deallocated by the caller.

The modifications compared to standard CRC32 is that no initial and final XOR is performed, and that the output is returned in LSB-first order.

Return value: Returns SHISHI_OK iff successful.

int shishi_md4 (Shishi * handle, const char * in, size_t inlen, char * out[MD4_DIGEST_SIZE]) handle: shishi handle as allocated by shishi_init().

in: input character array of data to hash.

inlen: length of input character array of data to hash.

Compute hash of data using MD4. The out buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_md5 (Shishi * handle, const char * in, size_t inlen, char * out[MD5_DIGEST_SIZE]) handle: shishi handle as allocated by shishi_init().

in: input character array of data to hash.

inlen: length of input character array of data to hash.

Compute hash of data using MD5. The out buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_hmac_md5 (Shishi * handle, const char * key, size_t keylen, const char * in, size_t inlen, char * outhash[MD5_DIGEST_SIZE]) handle: shishi handle as allocated by shishi_init().

key: input character array with key to use.

keylen: length of input character array with key to use.

in: input character array of data to hash.

inlen: length of input character array of data to hash.

Compute keyed checksum of data using HMAC-MD5. The outhash buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_hmac_sha1 (Shishi * handle, const char * key, size_t keylen, const char * in, size_t inlen, char * outhash[SHA1_DIGEST_SIZE]) handle: shishi handle as allocated by shishi_init().

key: input character array with key to use.

keylen: length of input character array with key to use.

in: input character array of data to hash.

inlen: length of input character array of data to hash.

Compute keyed checksum of data using HMAC-SHA1. The outhash buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_des_cbc_mac (Shishi * handle, const char key[DES_KEY_SIZE], const char iv[DES_BLOCK_SIZE], const char * in, size_t inlen, char * out[DES_BLOCK_SIZE]) handle: shishi handle as allocated by shishi_init().

in: input character array of data to hash.

inlen: length of input character array of data to hash.

Computed keyed checksum of data using DES-CBC-MAC. The out buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_arcfour (Shishi * handle, int decryptp, const char * key, size_t keylen, const char iv[258], char * ivout[258], const char * in, size_t inlen, char ** out) handle: shishi handle as allocated by shishi_init().

decryptp: 0 to indicate encryption, non-0 to indicate decryption.

key: input character array with key to use.

keylen: length of input key array.

in: input character array of data to encrypt/decrypt.

inlen: length of input character array of data to encrypt/decrypt.

out: newly allocated character array with encrypted/decrypted data.

Encrypt or decrypt data (depending on decryptp) using ARCFOUR. The out buffer must be deallocated by the caller.

The "initialization vector" used here is the concatenation of the sbox and i and j, and is thus always of size 256 + 1 + 1. This is a slight abuse of terminology, and assumes you know what you are doing. Don't use it if you can avoid to.

Return value: Returns SHISHI_OK iff successful.

int shishi_des (Shishi * handle, int decryptp, const char key[DES_KEY_SIZE], const char iv[DES_BLOCK_SIZE], char * ivout[DES_BLOCK_SIZE], const char * in, size_t inlen, char ** out) handle: shishi handle as allocated by shishi_init().

decryptp: 0 to indicate encryption, non-0 to indicate decryption.

in: input character array of data to encrypt/decrypt.

inlen: length of input character array of data to encrypt/decrypt.

out: newly allocated character array with encrypted/decrypted data.

Encrypt or decrypt data (depending on decryptp) using DES in CBC mode. The out buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_3des (Shishi * handle, int decryptp, const char key[DES3_KEY_SIZE], const char iv[DES3_BLOCK_SIZE], char * ivout[DES3_BLOCK_SIZE], const char * in, size_t inlen, char ** out) handle: shishi handle as allocated by shishi_init().

decryptp: 0 to indicate encryption, non-0 to indicate decryption.

in: input character array of data to encrypt/decrypt.

inlen: length of input character array of data to encrypt/decrypt.

out: newly allocated character array with encrypted/decrypted data.

Encrypt or decrypt data (depending on decryptp) using 3DES in CBC mode. The out buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.

int shishi_aes_cts (Shishi * handle, int decryptp, const char * key, size_t keylen, const char iv[AES_BLOCK_SIZE], char * ivout[AES_BLOCK_SIZE], const char * in, size_t inlen, char ** out) handle: shishi handle as allocated by shishi_init().

decryptp: 0 to indicate encryption, non-0 to indicate decryption.

key: input character array with key to use.

keylen: length of input character array with key to use.

in: input character array of data to encrypt/decrypt.

inlen: length of input character array of data to encrypt/decrypt.

out: newly allocated character array with encrypted/decrypted data.

Encrypt or decrypt data (depending on decryptp) using AES in CBC-CTS mode. The length of the key, keylen, decide if AES 128 or AES 256 should be used. The out buffer must be deallocated by the caller.

Return value: Returns SHISHI_OK iff successful.