source: project/wiki/crypto-tools @ 13201

Last change on this file since 13201 was 13201, checked in by Alaric Snell-Pym, 11 years ago

Changes applied for alaric (217.205.201.45) through svnwiki:

Initial release of the egg

File size: 8.3 KB
Line 
1[[tags:egg]]
2
3== Introduction
4
5The crypto-tools egg implements fundamental cryptographic operations. Currently, the main focus of this is an implementation of CBC (Cyphertext Block Chaining) and block padding, a technique that can be used to convert any block-based cypher into one capable of securely encrypting arbitrary-lengthed blobs.
6
7Naturally, this is a higher-order function; the underlying cypher must be provided as an encryption or decryption function that accepts a blob of a fixed size and returns an encrypted or decrypted blob of the same size. That function, along with the size of blob it works with, are passed to `make-cbc-encryptor` or `make-cbc-decryptor`, and it returns a function that encrypts or decrypts a blob of any size, given an "initialisation vector" or IV (a blob of the cipher's block size). The IV, in addition to whatever key the underlying cypher uses, must be the same for decryption as for encryption in order to get a successful result; the IV can either be derived as part of the key, or randomly generated before encryption then stored along with the cyphertext (perhaps encrypted).
8
9Note that the result of CBC encryption will always be slightly larger than the input, as it must be padded to the block size. If the input block is already an integral number of blocks long, then an entire extra padding block is required in order to make the padding invertible. The decryption operation automatically reverses the padding.
10
11This egg also provides the underlying block-padding and unpadding operations, along with a few functions that may be of use in other cryptographic operations: exclusive-oring blobs together, and converting blobs to and from hexadecimal strings, which can be useful for storing keys in human-readable form.
12
13== Examples
14
15Firstly, the functions to convert between blobs and hex strings:
16
17<examples>
18<example>
19<expr>(use crypto-tools)</expr>
20<expr>(blob->hexstring (string->blob "Hello, world!"))</expr>
21<result>"48656c6c6f2c20776f726c6421"</result>
22</example>
23<example>
24<expr>(blob->hexstring/uppercase (string->blob "Hello, world!"))</expr>
25<result>"48656C6C6F2C20776F726C6421"</result>
26</example>
27<expr>(use srfi-4)</expr>
28<expr>(blob->u8vector (hexstring->blob "010203"))</expr>
29<result>#u8(1 2 3)</result>
30</example>
31</examples>
32
33XORing blobs is easy (as long as they both have the same length):
34
35<examples>
36<example>
37<expr>(blob->u8vector (blob-xor (hexstring->blob "010203") (hexstring->blob "000200")))</expr>
38<result>#u8(1 0 3)</result>
39</example>
40</examples>
41
42The padding system can pad a blob to a fixed block size, as long as the blob is at most one byte shorter than the desired block size. It's up to you to split an input message into blocks then only attempt to pad the last block. If the input message is an integral number of blocks big, you should pad a zero-length block and make that the last block, unless you have an out-of-band method for indicating that the last block is not padded (but if you had that, you could use it to send a length, then pad the last block with random data, and on receipt, trim the result to the supplied length, removing the need for reversible padding anyway...)
43
44<examples>
45<example>
46<expr>(blob->hexstring (blob-pad (hexstring->blob "010203") 16))</expr>
47<result>"01020380000000000000000000000000"</result>
48</example>
49<example>
50<expr>(blob->hexstring (blob-unpad (hexstring->blob "01020380000000000000000000000000")))</expr>
51<result>"010203"</result>
52</example>
53<example>
54<expr>(blob->hexstring (blob-pad (hexstring->blob "") 16))</expr>
55<result>"80000000000000000000000000000000"</result>
56</example>
57<example>
58<expr>(blob->hexstring (blob-unpad (hexstring->blob "80000000000000000000000000000000")))</expr>
59<result>""</result>
60</example>
61</examples>
62
63Then, finally, we can get to the meat of it - CBC:
64
65<examples>
66<example>
67<expr>(use aes)</expr>
68<expr>(define encryptor (make-aes128-encryptor (hexstring->blob "00010203050607080A0B0C0D0F101112")))</expr>
69<expr>(define decryptor (make-aes128-decryptor (hexstring->blob "00010203050607080A0B0C0D0F101112")))</expr>
70<expr>(define cbc-encryptor (make-cbc-encryptor encryptor 16))</expr>
71<expr>(define cbc-decryptor (make-cbc-decryptor decryptor 16))</expr>
72<expr>(define iv (hexstring->blob "00010203050607080A0B0C0D0F101112"))</expr>
73<expr>(blob->hexstring (cbc-encryptor (string->blob "Hello, World!") iv))</expr>
74<result>"06acc6a8d17dec1563ac99f9a266bceb"</result>
75<expr>(blob->string (cbc-decryptor (hexstring->blob "06acc6a8d17dec1563ac99f9a266bceb") iv))</expr>
76<result>"Hello, World!"</result>
77</example>
78</examples>
79
80== Library functions
81
82<procedure>(blob->hexstring BLOB) => STRING</procedure>
83
84Takes an arbitrary blob, and returns a string made by encoding the blob in hexadecimal.
85
86<procedure>(blob->hexstring/uppercase BLOB) => STRING</procedure>
87
88As above, but using `ABCDEF` rather than `abcdef` in the string representation.
89
90<procedure>(hexstring->blob STRING) => BLOB</procedure>
91
92Creates a blob from a hexadecimal string. If the string is not even-lengthed, or contains characters outside of `[0-9a-fA-F]`, an error is signalled.
93
94<procedure>(blob-xor BLOB BLOB) => BLOB</procedure>
95
96Given two blobs of the same size, returns a blob of that size obtained by bitwise XORing the two input blobs together. Useful for chaining in cyphertext for each block in a CBC operation.
97
98<procedure>(blob-pad BLOB SIZE) => BLOB</procedure>
99
100Given a blob of at most SIZE-1 bytes, and a desired size, returns a blob of SIZE bytes by appending padding to the end of the input blob. The padding is a byte with the high bit set and no other bits set, followed by enough all-zero bytes to fill the block.
101
102<procedure>(blob-unpad BLOB) => BLOB</procedure>
103
104Reverses the effect of the previous function, by removing zero bytes from the end of the supplied blob, then removing a single byte with only the high bit set. If the input blob does not have valid padding at the end, an error is signalled.
105
106<procedure>(make-cbc-encryptor ENCRYPTOR BLOCKSIZE) => PROCESSOR</procedure>
107
108Given a block encryption function that accepts and returns blobs of BLOCKSIZE bytes, returns a CBC processor using the supplied encryptor that will encrypt arbitrary blobs, making them larger with padding in the process.
109
110<procedure>(make-cbc-decryptor ENCRYPTOR BLOCKSIZE) => PROCESSOR</procedure>
111
112Given a block decryption function that accepts and returns blobs of BLOCKSIZE bytes, returns a CBC processor using the supplied decryptor that will decrypt arbitrary blobs, stripping off padding.
113
114<procedure>(PROCESSOR BLOB IV) => BLOB</procedure>
115
116Given a blob of arbitrary size and an initialisation vector represented as a blob of BLOCKSIZE bytes, returns an encrypted/decrypted blob as appropriate.
117
118== Authors
119
120[[alaric-blagrave-snellpym|Alaric B. Snell-Pym]]
121
122== License
123
124  Copyright (c) 2003-2009, Warhead.org.uk Ltd
125  All rights reserved.
126
127  Redistribution and use in source and binary forms, with or without
128  modification, are permitted provided that the following conditions
129  are met:
130
131  Redistributions of source code must retain the above copyright
132  notice, this list of conditions and the following disclaimer.
133
134  Redistributions in binary form must reproduce the above copyright
135  notice, this list of conditions and the following disclaimer in the
136  documentation and/or other materials provided with the distribution.
137
138  Neither the names of Warhead.org.uk Ltd, Snell Systems, nor Kitten
139  Technologies, nor the names of their contributors may be used to
140  endorse or promote products derived from this software without
141  specific prior written permission.
142
143  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
144  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
145  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
146  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
147  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
148  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
149  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
150  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
151  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
152  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
153  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
154  POSSIBILITY OF SUCH DAMAGE.
155
156== Requirements
157
158None
159
160== Version History
161
162* 1.0: Initial release
Note: See TracBrowser for help on using the repository browser.