# Standard Security Module

The Standard Security module is an original implementation of several standards and techniques used in the field of cryptography. The module provides the objects than enables message hashing, symetric and assymetric ciphers and digital signature computation. The implementation follows the recommendation from NIST and PKCS and the standard reference that it implements is always attached to the underlying object.

## Hash objects

Hashing is the ability to generate an almost unique representation from a string. Although, there is no guarantee that two different string will not produce the same result -- known as a collision -- the sophistication of the hashing function attempt to minimize such eventuality. The hashing process is not reversible.

There are several hashing functions available in the public domain. To name a few, MD5 is the message digest 5, and SHA is the secure hash algorithm. The following table illustrates the size of the result with different hashing functions.

### Hasher function result size

Function | Result size
--- | ---
MD-2 | 128 bits
MD-4 | 128 bits
MD-5 | 128 bits
SHA-1 | 160 bits
SHA-224 | 224 bits
SHA-256 | 256 bits
SHA-384 | 384 bits
SHA-512 | 512 bits

### Hasher object

The `Hasher` class is a text hashing computation class. The class computes a hash value from a literal object, a buffer or an input stream. Once computed, the hash value is stored as an array of bytes that can be retrieved one by one or at all in the form of a string representation.

### Creating a hasher

Several hasher objects are available in the module. For example, the `Md5` object is the hasher object that implements the MD-5 algorithm. The constructor does not take any argument.

# get a MD-5 hasher const md (afnix:sec:Md5) # check the object afnix:sec:hasher-p md # true

The `compute` method computes the hash value. For example, the string "abc" returns the value "900150983CD24FB0D6963F7D28E17F72" which is 16 bytes long.

const hval (md:compute "abc")

### Creating a SHA hasher

There are several SHA objects that produces results of different size as indicated in the next table.

### Secure hash algorithm size and constructor

Hasher | Size | Constructor
--- | --- | ---
SHA-1 | 160 bits | Sha1
SHA-224 | 224 bits | Sha224
SHA-256 | 256 bits | Sha256
SHA-384 | 384 bits | Sha384
SHA-512 | 512 bits | Sha512

The `compute` method computes the hash value. For example, the string "abc" returns with SHA-1 the 20 bytes long value:

"A9993E364706816ABA3E25717850C26C9CD0D89D"

## Cipher key principles

Cipher key management is an important concept in the ciphering land. In a simple mode, a key is used by a cipher to encode some data. Although the key can be any sequence of bytes, it is preferable to have the key built from a specific source such like a pass-phrase. A cipher key comes basically into two flavors: keys for symmetric ciphers and keys for asymmetric ciphers. A key for a symmetric cipher is easy to derive and generally follows a standard process which is independent of the cipher itself. A key for an asymmetric cipher is more complex to derive and is generally dependent on the cipher itself.

### Key operations

The basic operations associated with a key are the key identification by type and size. The key type is an item that identifies the key nature. The `get-type` method returns the key type as specified by the table below.

### Supported key type

Key | Description
--- | ---
KSYM | Symmetric cipher key
KRSA | Asymmetric RSA cipher key
KMAC | Message authentication key
KDSA | Message signature key

The message authentication key as represented by the `KMAC` symbol is similar to the symmetric key. The key type can be obtained with the `get-type` method.

# get the key type const type (key:get-type)

The key size is the canonical size as specified by the key or the cipher specification. The `get-bits` returns the key size in bits. The `get-size` returns the key size in bytes rounded to the nearest value. The table below describes the nature of the key size returned.

### Key size nature

Key | Type | Description
--- | --- | ---
KSYM | byte | Byte array size
KRSA | bits | Modulus size
KMAC | byte | Byte array size
KDSA | bits | Signature size

const bits (key:get-bits) const size (key:get-size)

### Key representation

Unfortunately, it is not easy to represent a key, since the representation depends on the key's type. For example, a symmetric key can be formatted as a simple octet string. On the other hand, a RSA key has two components; namely the modulus and the exponent, which needs to be distinguished and therefore making the representation more difficult. Other cipher keys are even more complicated. For this reason, the representation model is a relaxed one. The `format` method can be called without argument to obtain an unique octet string representation if this representation is possible. If the key representation requires some parameters, the format method may accept one or several arguments to distinguish the key components.

### Key format method argument

Key | Argument | Description
--- | --- | ---
KSYM | none | Symmetric key octet string
KRSA | RSA-MODULUS | RSA modulus octet string
KRSA | RSA-PUBLIC-EXPONENT | RSA public exponent octet string
KRSA | RSA-SECRET-EXPONENT | RSA secret exponent octet string
KMAC | none | Message authentication key octet string
KDSA | DSA-P-PRIME | DSA secret prime octet string
KDSA | DSA-Q-PRIME | DSA secret prime octet string
KDSA | DSA-SECRET-KEY | DSA secret key
KDSA | DSA-PUBLIC-KEY | DSA public key
KDSA | DSA-PUBLIC-GENERATOR | DSA public generator

# get a simple key representation println (key:format) # get a rsa modulus key representation println (key:format afnix:sec:Key:RSA-MODULUS)

There are other key representations. The natural one is the byte representation for a symmetric key, while a number based representation is generally more convenient with asymmetric keys. The `get-byte` method returns a key byte by index if possible. The `get-relatif-key` returns a key value by relatif number if possible.

## Symmetric cipher key

### Creating a symmetric cipher key

The `Key` class can be used to create a cipher key suitable for a symmetric cipher. By default a 128 bits random key is generated, but the key can be also generated from an octet string.

const key (afnix:sec:Key) assert true (afnix:sec:key-p key)

The constructor also supports the use of an octet string representation of the key.

# create an octet string key const key (afnix:sec:Key "0123456789ABCDEF") assert true (afnix:sec:key-p key)

### Symmetric key functions

The basic operation associated with a symmetric key is the byte extraction. The `get-size` method can be used to determine the byte key size. Once the key size has been obtained, the key byte can be accessed by index with the `get-byte` method.

# create a 256 random symmetric key const key (afnix:sec:Key afnix:sec:Key:KSYM 256)

# get the key size const size (key:get-size) # get the first byte const byte (key:get-byte 0)

## Asymmetric cipher key

An asymmetric cipher key can be generated for a particular asymmetric cipher, such like RSA. Generally, the key contains several components identified as the public and secret key components. These components are highly dependent on the cipher type. Under some circumstances, all components might not be available.

### Creating an asymmetric cipher key

The `Key` class can be used to create a specific asymmetric cipher key. Generally, the key is created by type and and bits size.

# create a 1024 bits rsa key const key (afnix:sec:Key afnix:sec:Key:KRSA 1024)

An asymmetric cipher key constructor is extremely dependent on the cipher type. For this reason, there is no constructor that can operate with a pass-phrase.

### Asymmetric key functions

The basic operation associated with a asymmetric key is the relatif based representation which is generally available for all key components. For example, in the case of the RSA cipher, the modulus, the public and secret exponents can be obtained in a relatif number based representation with the help of the `get-relatif-key` method.

# create a 512 rsa key const key (afnix:sec:Key afnix:sec:Key:KRSA 512)

# get the key modulus const kmod ( key:get-relatif-key afnix:sec:Key:RSA-MODULUS) # get the public exponent const pexp ( key:get-relatif-key afnix:sec:Key:RSA-PUBLIC-EXPONENT) # get the secret exponent const sexp ( key:get-relatif-key afnix:sec:Key:RSA-SECRET-EXPONENT)

## Message authentication key

### Creating a message authentication key

The `Key` class can also be used to create a message authentication key suitable for a message authentication code generator or validator. By default a 128 bits random key is generated, but the key can be also generated from an octet string.

const key (afnix:sec:Key afnix:sec:Key:KMAC) assert true (afnix:sec:key-p key)

The constructor also supports the use of an octet string as a key representation.

# create an octet string key const key ( afnix:sec:Key afnix:sec:Key:KMAC "0123456789ABCDEF") assert true (afnix:sec:key-p key)

### Message authentication key functions

The basic operation associated with a message authentication key is the byte extraction. The `get-size` method can be used to determine the byte key size. Once the key size has been obtained, the key byte can be accessed by index with the `get-byte` method.

# create a 256 random message authentication key const key (afnix:sec:Key afnix:sec:Key:KMAC 256)

# get the key size const size (key:get-size) # get the first byte const byte (key:get-byte 0)

### Signature key functions

The basic operation associated with a signature key is the relatif based representation which is generally available for all key components. For example, in the case of the DSA signer, the prime numbers, the public and secret components can be obtained in a relatif number based representation with the help of the `get-relatif-key` method.

# create a 1024 dsa key const key (afnix:sec:Key afnix:sec:Key:KDSA)

# get the key size const size (key:get-size) # get the secret component const sexp ( key:get-relatif-key afnix:sec:Key:DSA-SECRET-KEY)

## Stream cipher

A stream cipher is an object that encodes an input stream into an output stream. The data are read from the input stream, encoded and transmitted onto the output stream. There are basically two types of stream ciphers known as symmetric cipher and asymmetric cipher.

### Symmetric cipher

A symmetric cipher is a cipher that encodes and decode data with the same key. Normally, the key is kept secret, and the data are encoded by block. For this reason, symmetric cipher are also called block cipher. In normal mode, a symmetric cipher is created with key and the data are encoded from an input stream as long as they are available. The block size depends on the nature of the cipher. As of today, the recommended symmetric cipher is the Advanced Encryption Standard or AES, also known as Rijndael.

### Asymmetric cipher

An asymmetric cipher is a cipher that encodes and decode data with two keys. Normally, the data are encoded with a public key and decoded with a private key. In this model, anybody can encode a data stream, but only one person can read them. Obviously, the model can be reverse to operate in a kind of signature mode, where only one person can encode the data stream and anybody can read them. Asymmetric cipher are particularly useful when operating on unsecured channels. In this model, one end can send its public key as a mean for other people to crypt data that can only be read by the sender who is supposed to have the private key. As of today, the recommended asymmetric ciphers are RSA and DH.

### Serial cipher

A serial cipher is a cipher that encodes and decode data on a byte basis. Normally, the data are encoded and decoded with the same key, thus making the symmetric cipher key, the ideal candidate for a serial cipher key. Since the data is encoded on a byte basis, it can be used efficiently with a stream. However, the serial cipher does not define a block size and therefore require some mechanism to prevent a buffer overrun when reading bytes from a stream. For this reason, the serial cipher defines a default serial block size that can be used to buffer the stream data. A method is provided in the class to control the buffer size and is by default set to 4Kib bytes.

### Cipher base class

The `Cipher` base class is an abstract class that supports the symmetric, asymmetric and serial cipher models. A cipher object has a name and is bound to a key that is used by the cipher. The class provides some base methods that can be used to retrieve some information about the cipher. The `get-name` method returns the cipher name. The `set-key` and `get-key` methods are both used to set or retrieve the cipher key.

The cipher operating mode can be found with the `get-reverse` method. If the `get-reverse` method returns true, the cipher is operating in decoding mode. Note that a `set-reverse` method also exists.

## Block cipher

A block cipher is an object that encodes an input stream with a symmetric cipher bound to a unique key. Since a block cipher is symmetric, the data can be coded and later decoded to their original form. The difference with the `Cipher` base class is that the `BlockCipher` class provides a `get-block-size` method which returns the cipher block size.

### Block Cipher base

The `BlockCipher` class is a base class for the block cipher engine. The class implements the `stream` method that reads from an input stream and write into an output stream. The `BlockCipher` class is an abstract class and cannot be instantiated by itself. The object is actually created by using a cipher algorithm class such like the `Aes` class.

trans count (cipher:stream os is)

The `stream` method returns the number of characters that have been encoded. Care should be taken that most of the stream cipher operates by block and therefore, will block until a complete block has been read from the input stream, unless the end of stream is read. The block cipher is always associated with a padding scheme. By default, the NIST 800-38A recommendation is associated with the block cipher, but can be changed with the `set-padding-mode`.

### Creating a block cipher

A `BlockCipher` object can be created with a cipher constructor. As of today, the Advanced Encryption Standard or AES is the recommended symmetric cipher. The `Aes` class creates a new block cipher that conforms to the AES standard.

const cipher (afnix:sec:Aes)

A block cipher can be created with a key and eventually a reverse flag. With one argument, the block cipher key is associated with the cipher. Such key can be created as indicated in the previous section. The reverse flag is used to determine if the cipher operate in encoding or decoding mode. By default, the cipher operates in coding mode.

# create a 256 bits random key const key (afnix:sec:Key afnix:sec:KSYM 256) # create an aes block cipher const aes (afnix:sec:Aes key)

### Block cipher information

The `BlockCipher` class is derived from the `Cipher` class and contains several methods that provide information about the cipher. This include the cipher block size with the `get-block-size` method.

println (aes:get-block-size)

## Input cipher

In the presence of a `Cipher` object, it is difficult to read an input stream and encode the character of a block basis. Furthermore, the existence of various method for block padding makes the coding operation even more difficult. For this reason, the `InputCipher` class provides the necessary method to code or decode an input stream in various mode of operations.

### Input cipher mode

The `InputCipher` class is an input stream that binds an input stream with a cipher. The class acts like an input stream, read the character from the bounded input stream and encode or decode them from the bended cipher. The `InputCipher` defines several modes of operations. In electronic codebook mode or ECB, the character are encoded in a block basis. In cipher block chaining mode, the block are encoded by doing an XOR operation with the previous block. Other modes are also available such like cipher feedback mode and output feedback mode.

### Creating an input cipher

By default an input cipher is created with a cipher object. Eventually, an input stream and/or the input mode can be specified at the object construction.

# create a key const key (afnix:sec:Key "hello world") # create a direct cipher const aes (afnix:sec:Aes key) # create an input cipher const ic (afnix:sec:InputCipher aes)

In this example, the input cipher is created in ECB mode. The input stream is later associated with the `set-is` method.

### Input cipher operation

The `InputCipher` class operates with one or several input streams. The `set-is` method sets the input stream. Read operation can be made with the help of the `valid-p` predicate.

while (ic:valid-p) (os:write (ic:read))

Since the `InputCipher` operates like an input stream, the stream can be read as long as the `valid-p` predicate returns true. Note that the `InputCipher` manages automatically the padding operations with the mode associated with the block cipher.

## Asymmetric cipher

A public cipher is an object that encodes an input stream with a asymmetric cipher bound to a public and secret key. In theory, there is no difference between a block cipher and a public cipher. Furthermore, the interface provided by the engine is the same for both objects.

### Public cipher

A public cipher is an asymmetric stream cipher which operates with an asymmetric key. The main difference between a block cipher and a public cipher is the key nature as well as the encoded block size. With an asymmetric cipher, the size of the message to encode is generally not the same as the encoded block, because a message padding operation must occurs for each message block.

trans count (cipher:stream os is)

The `stream` method returns the number of characters that have been encoded. Like the block cipher, the `stream` method encodes an input stream or a buffer object. The number of encoded bytes is returned by the method.

### Creating a public cipher

A `PublicCipher` object can be created with a cipher constructor. The RSA asymmetric cipher is the typical example of public cipher. It is created by binding a RSA key to it. For security reasons, the key size must be large enough, typically with a size of at lease 1024 bits.

const key (afnix:sec:Key afnix:sec:Key:KRSA 1024) const rsa (afnix:sec:Rsa key)

A block cipher can be created with a key and eventually a reverse flag. Additional constructors are available to support various padding mode. Such padding mode depends on the cipher type. For example, the RSA cipher supports the ISO 18033-2 padding mode with a KDF1 or KDF2 object. Such constructor requires a hasher object as well.

# create a 1024 bits rsa key const key (afnix:sec:Key afnix:sec:KRSA 1024) # create a SHA-1 hasher const ash (afnix:sec:Sha1) # create a rsa public cipher const rsa (afnix:sec:Rsa key ash "Demo") # set the padding mode rsa:set-padding-mode afnix:sec:Rsa:PAD-OAEP-K1

### Public cipher padding mode

Like any cipher, a padding mode can be associated with the cipher. The `set-padding-mode` method can be used to set or change the padding mode. Depending on the padding mode type, additional objects might be needed at construction.

### Supported cipher padding mode

Cipher | Padding mode | Default
--- | --- | ---
RSA | PKCS 1.5, PKCS 2.1, ISO/IEC 18033-2 | PKCS 1.5

The default padding mode depends on the cipher type. For RSA, the default padding mode is set to PKCS 1.5 for compatibility reason.

## Signature objects

A digital signature is a unique representation, supposedly non forgeable, designed to authenticate a document, in whatever form it is represented. For example, a signature is used to sign a certificate which is used during the process of establish a secured connection over the Internet. A signature can also be used to sign a courrier or keys as it is in the Openssh protocol.

Digital signatures come into several flavors eventually associated with the signed document. Sometimes, the signature acts as a container and permits to retrieve the document itself. Whatever the method, the principle remains the same. As of today technology, there are two standards used to sign document as indicated below.

### Digital signature standard

Standard | Name
--- | ---
DSS | Digital Signature Standard
RSA | RSA based signature

### Signer and signature objects

The process of generating a signature is done with the help of a `Signer` object. A signer object is a generic object, similar in functionality to the hasher object. The result produced by a signer object is a `Signature` object which holds the generated signature.

### Signature key

The process of generating a signature often requires the use of a key. Such key can be generated with the help of the `Key` object. The nature of the key will depend on the target signature. The following table is a resume of the supported keys.

### Digital signature key

Standard | Key | Signer
--- | --- | ---
DSS | KDSA | Dsa

In the case of DSS, a key can be generated automatically, although this process is time consuming. The default key size is 1024 bits.

const key (afnix:sec:Key afnix:sec:Key:KDSA) assert 1024 (key:get-bits)

### Creating a signer

A `Signer` object is created with a particular signature object such like DSA. The `Dsa` object is a signer object that implements the Digital Signature Algorithm as specified by the Digital Signature Standard (DSS) in FIPS-PUB 186-3.

# create a dsa signer const dsa (afnix:sec:Dsa key) assert true (afnix:sec:dsa-p dsa)

### Creating a signature

A signature is created with the help of the `compute` method. The `Signature` object is similar to the `Hasher` and operates with string or streams.

# create a signature object const sgn (dsa:compute "afnix") assert true (afnix:sec:signature-p sgn)

Once the signature is created, each data can be accessed directly with the associated component mapper. In the case of DSS, there are two components as show below.

# get the DSS S component sgn:get-relatif-component afnix:sec:Signature:DSA-S-COMPONENT # get the DSS R component sgn:get-relatif-component afnix:sec:Signature:DSA-R-COMPONENT