source: project/wiki/crypto-tools @ 13223

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

Changes applied for alaric (86.147.109.90) through svnwiki:

V1.1: CBC* mode

File size: 9.5 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<procedure>(make-cbc*-encryptor ENCRYPTOR BLOCKSIZE) => PROCESSOR</procedure>
120
121Given 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, and including an encrypted copy of the IV in the cyphertext.
122
123Although knowing the IV is not an advantage in itself to an attacker - after all, every encrypted block in the output is the IV for the rest of the encryption - we encrypt the IV as a precautionary measure; the process of generating an IV may reveal the state of entropy sources at the encoder, the current time, etc, which may be of interest to an attacker.
124
125The result of encryption will be one block larger than normal CBC encryption, due to the embedded IV.
126
127<procedure>(make-cbc*-decryptor ENCRYPTOR BLOCKSIZE) => PROCESSOR-WITHOUT-IV</procedure>
128
129Given 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.
130
131<procedure>(PROCESSOR-WITHOUT-IV BLOB) => BLOB</procedure>
132
133Given a blob returned by a make-cbc*-encryptor processor, returns a decrypted blob.
134
135== Authors
136
137[[alaric-blagrave-snellpym|Alaric B. Snell-Pym]]
138
139== License
140
141  Copyright (c) 2003-2009, Warhead.org.uk Ltd
142  All rights reserved.
143
144  Redistribution and use in source and binary forms, with or without
145  modification, are permitted provided that the following conditions
146  are met:
147
148  Redistributions of source code must retain the above copyright
149  notice, this list of conditions and the following disclaimer.
150
151  Redistributions in binary form must reproduce the above copyright
152  notice, this list of conditions and the following disclaimer in the
153  documentation and/or other materials provided with the distribution.
154
155  Neither the names of Warhead.org.uk Ltd, Snell Systems, nor Kitten
156  Technologies, nor the names of their contributors may be used to
157  endorse or promote products derived from this software without
158  specific prior written permission.
159
160  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
161  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
162  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
163  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
164  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
165  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
166  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
167  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
168  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
169  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
170  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
171  POSSIBILITY OF SUCH DAMAGE.
172
173== Requirements
174
175None
176
177== Version History
178
179* 1.1: CBC* mode
180* 1.0: Initial release
Note: See TracBrowser for help on using the repository browser.