Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: f937ee8e21
Fetching contributors…

Cannot retrieve contributors at this time

158 lines (158 sloc) 33.038 kb
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Ironclad</TITLE><LINK TYPE="text/css" TITLE="default" REL="stylesheet" MEDIA="screen" HREF="style.css" /></HEAD><BODY><H1>Ironclad</H1><P>Ironclad is a cryptography library written entirely in
Common Lisp. It includes support for several
popular <A HREF="#ciphers">ciphers</A>, <A HREF="#digests">digests</A>, and <A HREF="#macs">MACs</A>. Rudimentary support for <A HREF="#public-key">public-key cryptography</A> is included. For several implementations that support Gray
Streams, <A HREF="#gray-streams">support</A> is included for
convenient stream wrappers.</P><H2>Installation</H2><P>Ironclad can be downloaded at <A HREF="http://www.method-combination.net/lisp/files/ironclad.tar.gz">http://www.method-combination.net/lisp/files/ironclad.tar.gz</A>.
The latest version is 0.20.1.</P><P>It comes with an ASDF system definition, so <TT>(ASDF:OOS
'ASDF:LOAD-OP :IRONCLAD)</TT> should be all that you need to get started.
The testsuite can be run by substituting <TT>ASDF:TEST-OP</TT> for <TT>ASDF:LOAD-OP</TT> in the form above. All tests should pass successfully.
If they do not, you have found a bug; please report it.</P><H2>License</H2><P>Ironclad is released under a MIT-like license; you can do pretty
much anything you want to with the code except claim that you wrote
it.</P><H2>Ciphers</H2><DIV CLASS="lisp-symbol"><A NAME="make-cipher"></A><TT><STRONG>make-cipher</STRONG> <EM>name</EM> <EM><TT>&key</TT></EM> <EM>key</EM> <EM>mode</EM> <EM>initialization-vector</EM> <EM>padding</EM> =&gt; <EM>cipher</EM></TT><BR /></DIV><P>Return a cipher object suitable for use for both encryption and
decryption.</P><P><EM>name</EM> denotes the encryption algorithm to use. <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A> will tell you the names of all supported ciphers;
the short list of ones you are likely to be interested in is:</P><UL><LI>AES</LI><LI>DES</LI><LI>3DES</LI><LI>Blowfish</LI><LI>Twofish</LI><LI>RC5</LI><LI>RC6</LI><LI>Arcfour (RC4)</LI></UL><P><EM>name</EM> should be a symbol in the <TT>KEYWORD</TT> package; <TT>:AES</TT> for AES, <TT>:ARCFOUR</TT> for RC4, and so forth.</P><P><EM>mode</EM> describes the mode of operation for the cipher. Stream
ciphers such as Arcfour can operate in only one mode, <TT>stream</TT>.
Block ciphers such as AES and DES can operate in several different
modes:</P><UL><LI>ECB</LI><LI>CBC</LI><LI>OFB</LI><LI>CFB (note that CFB mode is 'n'-bit CFB, where 'n' is the <A HREF="#block-length" STYLE="symbol">block-length</A> of the cipher)</LI><LI>CTR</LI></UL><P><EM>mode</EM> should be a symbol in the <TT>KEYWORD</TT> or <TT>IRONCLAD</TT>
packages; <TT>:STREAM</TT>, <TT>IRONCLAD:OFB</TT>, and so forth. An error
will be signaled if <EM>mode</EM> is not appropriate for the cipher <EM>name</EM>.</P><P><EM>initialization-vector</EM> (IV) should be supplied only if <EM>mode</EM>
requires one. <EM>initialization-vector</EM> should be a <TT>(VECTOR
(UNSIGNED-BYTE 8))</TT>. The supplied IV should be the same length as the
<A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>name</EM>.</P><P><EM>key</EM> is, of course, the key for the cipher. <EM>key</EM> should be
a <TT>(VECTOR (UNSIGNED-BYTE 8))</TT>.</P><P>If <EM>padding</EM> is supplied, the specified padding method will be
used by <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> to handle short blocks when the <TT>:HANDLE-FINAL-BLOCK</TT> argument is supplied. Depending on the mode
specified, <EM>padding</EM> may be ignored (e.g. OFB and CFB modes do not
care about short blocks; neither do stream ciphers).</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>padding</EM> is currently ignored in all modes (and, by extension,
so is <TT>:HANDLE-FINAL-BLOCK</TT>). This oversight is expected to be
corrected in a future release.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="encrypt"></A><TT><STRONG>encrypt</STRONG> <EM>cipher</EM> <EM>plaintext</EM> <EM>ciphertext</EM> <EM><TT>&key</TT></EM> <EM>plaintext-start</EM> <EM>plaintext-end</EM> <EM>ciphertext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts data according to <EM>cipher</EM> from <EM>plaintext</EM>
starting at <EM>plaintext-start</EM> and continuing until <EM>plaintext-end</EM>. The encrypted data is placed in <EM>ciphertext</EM> starting at <EM>ciphertext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="decrypt"></A><TT><STRONG>decrypt</STRONG> <EM>cipher</EM> <EM>ciphertext</EM> <EM>plaintext</EM> <EM><TT>&key</TT></EM> <EM>ciphertext-start</EM> <EM>ciphertext-end</EM> <EM>plaintext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Decrypts data according to <EM>cipher</EM> from <EM>ciphertext</EM>
starting at <EM>ciphertext-start</EM> and continuing until <EM>ciphertext-end</EM>. The decrypted data is placed in <EM>plaintext</EM>
starting at <EM>plaintext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="encrypt-in-place"></A><TT><STRONG>encrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /><A NAME="decrypt-in-place"></A><TT><STRONG>decrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts or decrypts data in <EM>text</EM> between <EM>start</EM> and <EM>end</EM> "in-place" according to <EM>cipher</EM>. These functions are
shorthand for:</P><PRE>(encrypt cipher text text :plaintext-start start :plaintext-end end :ciphertext-start start)
(decrypt cipher text text :ciphertext-start start :ciphertext-end end :plaintext-start start)</PRE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> and <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A> do not support a <EM>handle-final-block</EM> parameter as <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> do.
If you need the functionality that <EM>handle-final-block</EM> provides,
then you need to use <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>n-bytes-consumed</EM> and <EM>n-bytes-produced</EM> may not always be
equal to the length of the data specified in the call to <A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> or <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A>. This subtlely is also
present in <A HREF="#encrypt" STYLE="symbol">encrypt</A> or <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-ciphers"></A><TT><STRONG>list-all-ciphers</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list of cipher-names that may be validly passed to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P><DIV CLASS="lisp-symbol"><A NAME="cipher-supported-p"></A><TT><STRONG>cipher-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="key-lengths"></A><TT><STRONG>key-lengths</STRONG> <EM>cipher</EM> =&gt; <EM>list</EM></TT><BR /></DIV><P>Return a list of valid key lengths for <EM>cipher</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="block-length"></A><TT><STRONG>block-length</STRONG> <EM>cipher</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Return the number of octets <EM>cipher</EM> processes at a time. This
function always returns 1 for stream ciphers.</P><H2>Digests</H2><P>Digest functions, also known as hash functions, produce
fixed-length output (a <EM>digest</EM> or <EM>hash</EM>) from a
variable-length message. The simplest example of a digest function is
one that adds up all the bytes in the message modulo 256. This digest
function fails one test of a cryptographically secure hash function: it
must be difficult to find a message with a given digest. It also fails
the other test: it must be difficult to find two messages with the same
digest.</P><P>Ironclad provides several cryptographically secure digest functions
and several non-cryptographically secure digest functions.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">In the functions below, messages or parts thereof are provided
as octet vectors; Ironclad has no facilities for producing digests of
strings. If you need to obtain the digest of a string, then you need to
figure out how to convert it to an octet vector first. This is a
deliberate design decision. Characters are not equivalent to bytes.
See your local Unicode guru for more details.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="make-digest"></A><TT><STRONG>make-digest</STRONG> <EM>digest-name</EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Returns a digest object. <EM>digest-name</EM> is a keyword naming the
algorithm you wish <EM>digester</EM> to use. The algorithms you are likely
to want to use are:</P><UL><LI>MD4</LI><LI>MD5</LI><LI>SHA1</LI><LI>SHA256</LI><LI>Tiger</LI><LI>Adler32</LI><LI>CRC32</LI></UL><P>Other legitimate digest names can be found by calling <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>. Like <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>, <EM>digest-name</EM> should be
a symbol in the <TT>KEYWORD</TT> package.</P><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>thing</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>(values)</EM></TT><BR /></DIV><P>Updates the internal state of <EM>digester</EM> with the contents of <EM>thing</EM>. The exact method is determined by the type of THING.</P><P>There are several methods defined on this generic function that
take a particular digester and a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
(*))</TT> as well as the usual <EM>start</EM> and <EM>end</EM> keyword
arguments. These methods update the state of <EM>digester</EM> with the
subsequence of the array denoted by <EM>start</EM> and <EM>end</EM>. They are
note listed here because there's one method for every type of digest
that Ironclad provides, and listing them would get very tedious
for no benefit. An example should suffice.</P><PRE>(let ((digester (ironclad:make-digest :sha1))
(array (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0)))
;; Update with 16 zeroes.
(ironclad:update-digest digester array)
;; Update with 8 ones.
(fill array 1 :start 2 :end 10)
(ironclad:update-digest digester array :start 2 :end 10))</PRE><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>(stream stream)</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Update the internal state of <EM>digester</EM> with the contents of <EM>stream</EM>, which must respond to <TT>READ-BYTE</TT> or <TT>READ-SEQUENCE</TT>
with a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT> and return <EM>digester</EM>. This method is implemented on top of the previous method
for sequences It differs from <A HREF="#digest-stream" STYLE="symbol">digest-stream</A>, below, in that you
may need to digest data before or after the contents of <EM>stream</EM>
(this happens, for instance, when signing the contents of some file).</P><DIV CLASS="lisp-symbol"><A NAME="produce-digest"></A><TT><STRONG>produce-digest</STRONG> <EM>digester</EM> <EM><TT>&key</TT></EM> <EM>digest-start</EM> <EM>digest</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Return the digest of the data processed by <EM>digester</EM> so far.
The internal state of <EM>digester</EM> is not modified; this feature makes
it possible to compute a "rolling digest" of a document.</P><P>If <EM>digest</EM> is provided, the computed digest will be placed
into <EM>digest</EM> starting at <EM>digest-start</EM>. <EM>digest</EM> must be
a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>. An <A HREF="#insufficient-buffer-space" STYLE="symbol">insufficient-buffer-space</A> error will be signaled if there is
insufficient space in <EM>digest</EM>.</P><H3>High-level convenience functions</H3><P>Several high-level convenience functions that encapsulate common
sequences of <A HREF="#make-digest" STYLE="symbol">make-digest</A>, <A HREF="#update-digest" STYLE="symbol">update-digest</A> and <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> are provided by Ironclad as well.</P><DIV CLASS="lisp-symbol"><A NAME="digest-sequence"></A><TT><STRONG>digest-sequence</STRONG> <EM>digest-name</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the subsequence of <EM>sequence</EM> bounded by
<EM>start</EM> and <EM>end</EM>, according to <EM>digest-name</EM>. <EM>sequence</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-stream"></A><TT><STRONG>digest-stream</STRONG> <EM>digest-name</EM> <EM>stream</EM> <EM><TT>&key</TT></EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the stream specified by <EM>stream</EM>. <TT>READ-BYTE</TT> must be a legal operation on <EM>stream</EM>
and return an <TT>(UNSIGNED-BYTE 8)</TT>. In a similar fashion, <TT>READ-SEQUENCE</TT> on <EM>stream</EM> must support reading into a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-file"></A><TT><STRONG>digest-file</STRONG> <EM>digest-name</EM> <EM>pathname</EM> <EM><TT>&key</TT></EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the file named by <EM>pathname</EM>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-digests"></A><TT><STRONG>list-all-digests</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list whose elements may be validly passed to <A HREF="#make-digest" STYLE="symbol">make-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-supported-p"></A><TT><STRONG>digest-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="digest-length"></A><TT><STRONG>digest-length</STRONG> <EM>digest</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Returns the length of the digest computed by <EM>digest</EM>, which
may be a digest-name or a digest instance.</P><H2>Message authentication codes</H2><P>A message authentication code is a cryptographic function of some
data and a user-specified key. Only a person knowing the key can
recompute the MAC for the given message. A MAC is useful where
maintaining data integrity is required, but the secrecy of the data is
not paramount.</P><P>Ironclad provides two different kinds of MACs: HMACs, specified in
<A HREF="http://www.ietf.org/rfc/rfc2109.txt">RFC 2104</A>, and CMACs,
specified in <A HREF="http://www.ietf.org/rfc/rfc4493.txt">RFC 4493</A>
and NIST document 800-38B.</P><H3>HMACs</H3><P>Instances of HMACs are constructed by specifying a secret key and a
digest-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-hmac"></A><TT><STRONG>make-hmac</STRONG> <EM>key</EM> <EM>digest-name</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Return an HMAC instance based on the hash function <EM>digest-name</EM> with secret key <EM>key</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="update-hmac"></A><TT><STRONG>update-hmac</STRONG> <EM>hmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>hmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="hmac-digest"></A><TT><STRONG>hmac-digest</STRONG> <EM>hmac</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>hmac</EM> thus far.
The internal state of <EM>hmac</EM> is not modified; this feature makes it
possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#digest-length" STYLE="symbol">digest-length</A> of <EM>digest-name</EM>
passed to <A HREF="#make-hmac" STYLE="symbol">make-hmac</A> when <EM>hmac</EM> was constructed.</P><H3>CMACs</H3><P>Instances of CMACs are constructed by specifying a secret key and a
cipher-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-cmac"></A><TT><STRONG>make-cmac</STRONG> <EM>key</EM> <EM>cipher-name</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Return a CMAC instance based on the cipher <EM>cipher-name</EM> with
secret key <EM>key</EM>. <EM>cipher-name</EM> must have a <A HREF="#block-length" STYLE="symbol">block-length</A>
of either 8 or 16; this restriction is satisfied by most ciphers in
Ironclad with the notable exception of stream ciphers. <EM>key</EM> must
be an acceptable key for <EM>cipher-name</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="update-cmac"></A><TT><STRONG>update-cmac</STRONG> <EM>cmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>cmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="cmac-digest"></A><TT><STRONG>cmac-digest</STRONG> <EM>cmac</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>cmac</EM> thus far.
The internal state of <EM>cmac</EM> is not modified; this feature makes it
possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>cipher-name</EM>
passed to <A HREF="#make-cmac" STYLE="symbol">make-cmac</A> when <EM>cmac</EM> was constructed.</P><H2>Public-key Operations</H2><P>Ironclad includes support for DSA signing and verification.
Support for RSA encryption and decryption is provided as well, but it is
"raw"--the various formatting schemes (e.g. PKCS-1) must be implemented
by the user at this time.</P><H3>Key construction</H3><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>public-key</EM></TT><BR /></DIV><P>Return a public key according to <EM>kind</EM>. The <EM>&key</EM>
arguments vary according to <EM>kind</EM>. The interesting bits are in the
methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA public key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, and <EM>y</EM>
are the usual parameters for DSA keys discussed in the literature.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a private key according to <EM>kind</EM>. The <EM>&key</EM>
arguments vary according to <EM>kind</EM>. The interesting bits are in the
methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM>x</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA private key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, <EM>y</EM>, and
<EM>x</EM> are the usual parameters for DSA keys discussed in the
literature.</P><H3>Digital signatures</H3><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Return a signature of <EM>message</EM> between <EM>start</EM> and <EM>end</EM> signed with <EM>key</EM>; the class of <EM>key</EM> determines the class of
<EM>signature</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>(key dsa-private-key)</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>This method places an additional constraint on the size of <EM>message</EM> specified by <EM>start</EM> and <EM>end</EM>: it must be exactly
20 bytes long (the length of a SHA-1 digest). <EM>signature</EM> is a <A HREF="#dsa-signature" STYLE="symbol">dsa-signature</A> object.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>key</EM> <EM>message</EM> <EM>signature</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Verify whether <EM>signature</EM> is the signature of <EM>message</EM>
between <EM>start</EM> and <EM>end</EM> using <EM>key</EM>. Return T or NIL
depending on the result of verification.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>(key dsa-public-key)</EM> <EM>message</EM> <EM>(signature dsa-signature)</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><H4>Signature objects</H4><P>There is no one "right" way to format signatures into octet
vectors; different applications may have different requirements. <A HREF="#sign-message" STYLE="symbol">sign-message</A> therefore returns objects and lets the user determine
how to best format the values contained therein.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature"></A><TT><STRONG>dsa-signature</STRONG></TT><BR /></DIV><P>A DSA signature object.</P><DIV CLASS="lisp-symbol"><A NAME="make-dsa-signature"></A><TT><STRONG>make-dsa-signature</STRONG> <EM>r</EM> <EM>s</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Returns a DSA signature with the provided <EM>r</EM> and <EM>s</EM>
values. <EM>r</EM> and <EM>s</EM> may be either integers or they may be
20-byte octet vectors.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-r"></A><TT><STRONG>dsa-signature-r</STRONG> <EM>dsa-signature</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>r</EM> value of the provided DSA signature.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-s"></A><TT><STRONG>dsa-signature-s</STRONG> <EM>dsa-signature</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>s</EM> value of the provided DSA signature.</P><H3>Encryption and decryption</H3><DIV CLASS="lisp-symbol"><A NAME="encrypt-message"></A><TT><STRONG>encrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>encrypted-message</EM></TT><BR /></DIV><DIV CLASS="lisp-symbol"><A NAME="decrypt-message"></A><TT><STRONG>decrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>decrypted-message</EM></TT><BR /></DIV><H2>Gray Streams</H2><P>Ironclad includes support for several convenient stream
abstractions based on Gray streams. Gray streams support in Ironclad is
included for SBCL, CMUCL, OpenMCL, and Allegro.</P><H3>Octet streams</H3><P>Octet streams are very similar to Common Lisp's <A HREF="#string-stream" STYLE="symbol">string-stream</A>,
except they deal in octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-input-stream"></A><TT><STRONG>make-octet-input-stream</STRONG> <EM>buffer</EM> <EM><TT>&optional</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>octet-input-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-input-stream" STYLE="symbol">make-string-input-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-output-stream"></A><TT><STRONG>make-octet-output-stream</STRONG> =&gt; <EM>octet-output-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-output-stream" STYLE="symbol">make-string-output-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="get-output-stream-octets"></A><TT><STRONG>get-output-stream-octets</STRONG> <EM>stream</EM> =&gt; <EM>octet-vector</EM></TT><BR /></DIV><P>As <A HREF="#get-output-stream-string" STYLE="symbol">get-output-stream-string</A>, only with an octet output-steam
instead of a string output-stream.</P><H3>Digest streams</H3><P>Digest streams compute a digest of the data written to them
according to a specific digest algorithm.</P><P>Example:</P><PRE>(defun frobbing-function (stream)
;; We want to compute a digest of the data being written to STREAM
;; without involving our callees in the process.
(let* ((digesting-stream (crypto:make-digesting-stream :sha1))
(stream (make-broadcast-stream stream digesting-stream)))
;; Feed data to STREAM.
(frob-guts stream)
;; Do something with the digest computed.
(... (crypto:produce-digest digesting-stream) ...)
...))</PRE><DIV CLASS="lisp-symbol"><A NAME="make-digesting-stream"></A><TT><STRONG>make-digesting-stream</STRONG> <EM>digest</EM> =&gt; <EM>stream</EM></TT><BR /></DIV><P>Make a stream that computes a digest of the data written to it
according to the algorithm <EM>digest-name</EM>. <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> may
be used to obtain a digest of all the data written to the stream.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">Calling <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> on a digest stream does not alter
the internal state of the digest.</TD></TR></TABLE><H2>Utility Functions</H2><DIV CLASS="lisp-symbol"><A NAME="ub16ref/le"></A><TT><STRONG>ub16ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/le"></A><TT><STRONG>ub32ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/le"></A><TT><STRONG>ub64ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>This family of functions accesses an unsigned 16-bit, 32-bit or
64-bit value stored in little-endian order starting at <EM>index</EM> in <EM>array</EM>. <EM>array</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
(*))</TT>. These functions are SETFable.</P><DIV CLASS="lisp-symbol"><A NAME="ub16ref/be"></A><TT><STRONG>ub16ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/be"></A><TT><STRONG>ub32ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/be"></A><TT><STRONG>ub64ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>As the above, only the value is stored in big-endian order.</P><DIV CLASS="lisp-symbol"><A NAME="byte-array-to-hex-string"></A><TT><STRONG>byte-array-to-hex-string</STRONG> <EM>vector</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>element-type</EM> =&gt; <EM>string</EM></TT><BR /><A NAME="ascii-string-to-byte-array"></A><TT><STRONG>ascii-string-to-byte-array</STRONG> <EM>string</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>byte-array-to-hex-string</TT> converts the bytes of <EM>vector</EM>
between <EM>start</EM> and <EM>end</EM> into a hexadecimal string. It is
useful for converting digests to a more readable form. <EM>element-type</EM> indicates the element-type of the returned string.</P><P><TT>ascii-string-to-byte-array</TT> is provided as a quick and dirty way
to convert a string to a byte array suitable for feeding to <A HREF="#update-digest" STYLE="symbol">update-digest</A> or <A HREF="#encrypt" STYLE="symbol">encrypt</A>. Care should be taken to ensure that
the provided string is actually an ASCII string. <EM>start</EM> and <EM>end</EM> have their usual interpretations.</P><DIV CLASS="lisp-symbol"><A NAME="octets-to-integer"></A><TT><STRONG>octets-to-integer</STRONG> <EM>octet-vec</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>big-endian</EM> <EM>n-bits</EM> =&gt; <EM>number</EM></TT><BR /><A NAME="integer-to-octets"></A><TT><STRONG>integer-to-octets</STRONG> <EM>bignum</EM> <EM><TT>&key</TT></EM> <EM>n-bits</EM> <EM>big-endian</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>octets-to-integer</TT> converts the bytes of <EM>octet-vec</EM> between
<EM>start</EM> and <EM>end</EM> to an integer as though the bytes denoted a
number in base 256. <EM>big-endian</EM> is a boolean indicating whether
the bytes are to be read in big-endian or little-endian order. <EM>n-bits</EM> specifies how many bits should be considered as significant
in the resulting number.</P><P><TT>integer-to-octets</TT> is the reverse operation.</P><DIV CLASS="lisp-symbol"><A NAME="expt-mod"></A><TT><STRONG>expt-mod</STRONG> <EM>n</EM> <EM>exponent</EM> <EM>modulus</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Raises <EM>n</EM> to the <EM>exponent</EM> power modulo <EM>modulus</EM> in
a more efficient fashion than <TT>(MOD (EXPT N EXPONENT) MODULUS)</TT>.</P><H2>Conditions</H2><DIV CLASS="lisp-symbol"><A NAME="ironclad-error"></A><TT><STRONG>ironclad-error</STRONG></TT><BR /></DIV><P>All errors signaled by Ironclad are of this type. This type is a
direct subtype of <TT>SIMPLE-ERROR</TT> without any extra slots or
options.</P><DIV CLASS="lisp-symbol"><A NAME="initialization-vector-not-supplied"></A><TT><STRONG>initialization-vector-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled by <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> when an initialization
vector is not provided and the requested mode requires an initialization
vector.</P><DIV CLASS="lisp-symbol"><A NAME="invalid-initialization-vector"></A><TT><STRONG>invalid-initialization-vector</STRONG></TT><BR /></DIV><P>This error is signaled when an invalid initialization vector is
supplied to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> (e.g. when the length of the initialization
vector does not match the block length of the cipher).</P><DIV CLASS="lisp-symbol"><A NAME="invalid-key-length"></A><TT><STRONG>invalid-key-length</STRONG></TT><BR /></DIV><P>This error is signaled when the key provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is
not of an acceptable length for the requested cipher.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-cipher"></A><TT><STRONG>unsupported-cipher</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>cipher-name</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#cipher-supported-p" STYLE="symbol">cipher-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-mode"></A><TT><STRONG>unsupported-mode</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>mode</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#mode-supported-p" STYLE="symbol">mode-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-digest"></A><TT><STRONG>unsupported-digest</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>digest-name</EM> provided to <A HREF="#make-digest" STYLE="symbol">make-digest</A> is not <A HREF="#digest-supported-p" STYLE="symbol">digest-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="insufficient-buffer-space"></A><TT><STRONG>insufficient-buffer-space</STRONG></TT><BR /></DIV><P>This error is signaled when Ironclad needs to stuff some data into a
buffer (e.g. when the user provides <EM>digest</EM> to <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>) and
there is insufficient space.</P><DIV CLASS="lisp-symbol"><A NAME="key-not-supplied"></A><TT><STRONG>key-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled when a <TT>:KEY</TT> argument is not provided
to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P></BODY></HTML>
Jump to Line
Something went wrong with that request. Please try again.