source: project/wiki/crypto-tools @ 13202

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

Changes applied for alaric (217.205.201.45) through svnwiki:

Markup correction

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<example>
28<expr>(use srfi-4)</expr>
29<expr>(blob->u8vector (hexstring->blob "010203"))</expr>
30<result>#u8(1 2 3)</result>
31</example>
32</examples>
33
34XORing blobs is easy (as long as they both have the same length):
35
36<examples>
37<example>
38<expr>(blob->u8vector (blob-xor (hexstring->blob "010203") (hexstring->blob "000200")))</expr>
39<result>#u8(1 0 3)</result>
40</example>
41</examples>
42
43The 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...)
44
45<examples>
46<example>
47<expr>(blob->hexstring (blob-pad (hexstring->blob "010203") 16))</expr>
48<result>"01020380000000000000000000000000"</result>
49</example>
50<example>
51<expr>(blob->hexstring (blob-unpad (hexstring->blob "01020380000000000000000000000000")))</expr>
52<result>"010203"</result>
53</example>
54<example>
55<expr>(blob->hexstring (blob-pad (hexstring->blob "") 16))</expr>
56<result>"80000000000000000000000000000000"</result>
57</example>
58<example>
59<expr>(blob->hexstring (blob-unpad (hexstring->blob "80000000000000000000000000000000")))</expr>
60<result>""</result>
61</example>
62</examples>
63
64Then, finally, we can get to the meat of it - CBC:
65
66<examples>
67<example>
68<expr>(use aes)</expr>
69<expr>(define encryptor (make-aes128-encryptor (hexstring->blob "00010203050607080A0B0C0D0F101112")))</expr>
70<expr>(define decryptor (make-aes128-decryptor (hexstring->blob "00010203050607080A0B0C0D0F101112")))</expr>
71<expr>(define cbc-encryptor (make-cbc-encryptor encryptor 16))</expr>
72<expr>(define cbc-decryptor (make-cbc-decryptor decryptor 16))</expr>
73<expr>(define iv (hexstring->blob "00010203050607080A0B0C0D0F101112"))</expr>
74<expr>(blob->hexstring (cbc-encryptor (string->blob "Hello, World!") iv))</expr>
75<result>"06acc6a8d17dec1563ac99f9a266bceb"</result>
76<expr>(blob->string (cbc-decryptor (hexstring->blob "06acc6a8d17dec1563ac99f9a266bceb") iv))</expr>
77<result>"Hello, World!"</result>
78</example>
79</examples>
80
81== Library functions
82
83<procedure>(blob->hexstring BLOB) => STRING</procedure>
84
85Takes an arbitrary blob, and returns a string made by encoding the blob in hexadecimal.
86
87<procedure>(blob->hexstring/uppercase BLOB) => STRING</procedure>
88
89As above, but using `ABCDEF` rather than `abcdef` in the string representation.
90
91<procedure>(hexstring->blob STRING) => BLOB</procedure>
92
93Creates 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.
94
95<procedure>(blob-xor BLOB BLOB) => BLOB</procedure>
96
97Given 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.
98
99<procedure>(blob-pad BLOB SIZE) => BLOB</procedure>
100
101Given 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.
102
103<procedure>(blob-unpad BLOB) => BLOB</procedure>
104
105Reverses 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.
106
107<procedure>(make-cbc-encryptor ENCRYPTOR BLOCKSIZE) => PROCESSOR</procedure>
108
109Given 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.
110
111<procedure>(make-cbc-decryptor ENCRYPTOR BLOCKSIZE) => PROCESSOR</procedure>
112
113Given 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.
114
115<procedure>(PROCESSOR BLOB IV) => BLOB</procedure>
116
117Given a blob of arbitrary size and an initialisation vector represented as a blob of BLOCKSIZE bytes, returns an encrypted/decrypted blob as appropriate.
118
119== Authors
120
121[[alaric-blagrave-snellpym|Alaric B. Snell-Pym]]
122
123== License
124
125  Copyright (c) 2003-2009, Warhead.org.uk Ltd
126  All rights reserved.
127
128  Redistribution and use in source and binary forms, with or without
129  modification, are permitted provided that the following conditions
130  are met:
131
132  Redistributions of source code must retain the above copyright
133  notice, this list of conditions and the following disclaimer.
134
135  Redistributions in binary form must reproduce the above copyright
136  notice, this list of conditions and the following disclaimer in the
137  documentation and/or other materials provided with the distribution.
138
139  Neither the names of Warhead.org.uk Ltd, Snell Systems, nor Kitten
140  Technologies, nor the names of their contributors may be used to
141  endorse or promote products derived from this software without
142  specific prior written permission.
143
144  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
145  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
146  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
147  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
148  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
149  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
150  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
151  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
152  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
153  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
154  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
155  POSSIBILITY OF SUCH DAMAGE.
156
157== Requirements
158
159None
160
161== Version History
162
163* 1.0: Initial release
Note: See TracBrowser for help on using the repository browser.