1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>KLone: cipher.c Source File</title>
<link href="kl.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.9.1 -->
<div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a></div>
<div class="nav">
<a class="el" href="dir_000000.html">src</a> / <a class="el" href="dir_000006.html">libcodec</a></div>
<h1>cipher.c</h1><a href="cipher_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*</span>
00002 <span class="comment"> * Copyright (c) 2005, 2006 by KoanLogic s.r.l. <http://www.koanlogic.com></span>
00003 <span class="comment"> * All rights reserved.</span>
00004 <span class="comment"> *</span>
00005 <span class="comment"> * This file is part of KLone, and as such it is subject to the license stated</span>
00006 <span class="comment"> * in the LICENSE file which you have received as part of this distribution.</span>
00007 <span class="comment"> *</span>
00008 <span class="comment"> * $Id: cipher.c,v 1.10 2006/01/09 12:38:38 tat Exp $</span>
00009 <span class="comment"> */</span>
00010
00011 <span class="preprocessor">#include "klone_conf.h"</span>
00012 <span class="preprocessor">#include <u/libu.h></span>
00013 <span class="preprocessor">#include <<a class="code" href="codec_8h.html">klone/codec.h</a>></span>
00014 <span class="preprocessor">#include <<a class="code" href="ccipher_8h.html">klone/ccipher.h</a>></span>
00015 <span class="preprocessor">#include <<a class="code" href="utils_8h.html">klone/utils.h</a>></span>
00016
00017 <span class="keyword">enum</span> { <a class="code" href="cipher_8c.html#a9a3">CODEC_CIPHER_MAX_INPUT</a> = 4096 <span class="comment">/* max src block size for transform() */</span> };
00018
<a name="l00019"></a><a class="code" href="cipher_8c.html#a0">00019</a> <span class="keyword">typedef</span> int (*EVP_Update_t)(EVP_CIPHER_CTX *ctx, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *out,
00020 <span class="keywordtype">int</span> *outl, <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *in, <span class="keywordtype">int</span> inl);
<a name="l00021"></a><a class="code" href="cipher_8c.html#a1">00021</a> <span class="keyword">typedef</span> int (*EVP_Final_ex_t)(EVP_CIPHER_CTX *ctx, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *out,
00022 <span class="keywordtype">int</span> *outl);
00023
00024 <span class="keyword">struct </span>codec_cipher_s
00025 {
00026 <a class="code" href="structcodec__s.html">codec_t</a> codec;
00027 <span class="keyword">const</span> EVP_CIPHER *cipher; <span class="comment">/* encryption cipher algorithm */</span>
00028 EVP_CIPHER_CTX cipher_ctx; <span class="comment">/* encrypt context */</span>
00029 <span class="keywordtype">char</span> *cbuf;
00030 size_t coff, ccount, cbuf_size;
00031 <a class="code" href="cipher_8c.html#a0">EVP_Update_t</a> update; <span class="comment">/* EVP_{Encrypt,Decrypt}Update func ptr */</span>
00032 <a class="code" href="cipher_8c.html#a1">EVP_Final_ex_t</a> <span class="keyword">final</span>; <span class="comment">/* EVP_{Encrypt,Decrypt}Final_ex func ptr */</span>
00033 };
00034
<a name="l00035"></a><a class="code" href="cipher_8c.html#a2">00035</a> <span class="keyword">typedef</span> <span class="keyword">struct </span>codec_cipher_s <a class="code" href="cipher_8c.html#a2">codec_cipher_t</a>;
00036
00037 <span class="keyword">static</span> <span class="keywordtype">void</span> codec_cbufcpy(codec_cipher_t *cc, <span class="keywordtype">char</span> *dst, size_t *dcount)
00038 {
00039 size_t count;
00040
00041 count = <a class="code" href="utils_8h.html#a0">MIN</a>(*dcount, cc->ccount);
00042
00043 memcpy(dst, cc->cbuf + cc->coff, count);
00044 cc->ccount -= count;
00045 <span class="keywordflow">if</span>(cc->ccount)
00046 cc->coff += count;
00047 <span class="keywordflow">else</span>
00048 cc->coff = 0;
00049 *dcount = count;
00050 }
00051
00052 <span class="keyword">static</span> ssize_t cipher_flush(<a class="code" href="structcodec__s.html">codec_t</a> *codec, <span class="keywordtype">char</span> *dst, size_t *dcount)
00053 {
00054 <a class="code" href="cipher_8c.html#a2">codec_cipher_t</a> *cc;
00055 <span class="keywordtype">int</span> wr;
00056
00057 dbg_err_if (codec == NULL);
00058 dbg_err_if (dst == NULL);
00059 dbg_err_if (dcount == NULL);
00060
00061 cc = (<a class="code" href="cipher_8c.html#a2">codec_cipher_t</a>*)codec;
00062
00063 <span class="keywordflow">for</span>(;;)
00064 {
00065 <span class="keywordflow">if</span>(cc->ccount)
00066 {
00067 codec_cbufcpy(cc, dst, dcount);
00068 <span class="keywordflow">return</span> CODEC_FLUSH_CHUNK; <span class="comment">/* call flush again */</span>
00069 }
00070
00071 <span class="keywordflow">if</span>(cc->final)
00072 {
00073 wr = -1; <span class="comment">/* just used to return an int value */</span>
00074 dbg_err_if(!cc->final(&cc->cipher_ctx, cc->cbuf, &wr));
00075
00076 cc-><a class="code" href="structcodec__s.html#o4">ccount</a> += wr;
00077 cc->final = NULL; <span class="comment">/* can be called just once */</span>
00078
00079 <span class="keywordflow">if</span>(wr)
00080 <span class="keywordflow">continue</span>;
00081 }
00082 <span class="keywordflow">break</span>;
00083 }
00084
00085 *dcount = 0;
00086 <span class="keywordflow">return</span> CODEC_FLUSH_COMPLETE;
00087 err:
00088 <span class="keywordflow">return</span> -1;
00089 }
00090
00091 <span class="keyword">static</span> ssize_t cipher_transform(<a class="code" href="structcodec__s.html">codec_t</a> *codec, <span class="keywordtype">char</span> *dst, size_t *dcount,
00092 <span class="keyword">const</span> <span class="keywordtype">char</span> *src, size_t src_sz)
00093 {
00094 <a class="code" href="cipher_8c.html#a2">codec_cipher_t</a> *cc;
00095 ssize_t c;
00096 <span class="keywordtype">int</span> wr;
00097
00098 dbg_err_if (codec == NULL);
00099 dbg_err_if (src == NULL);
00100 dbg_err_if (dst == NULL);
00101 dbg_err_if (dcount == NULL || *dcount == 0);
00102 dbg_err_if (src_sz == 0);
00103
00104 cc = (<a class="code" href="cipher_8c.html#a2">codec_cipher_t</a>*)codec;
00105
00106 c = 0;
00107 <span class="keywordflow">for</span>(;;)
00108 {
00109 <span class="keywordflow">if</span>(cc->ccount)
00110 {
00111 codec_cbufcpy(cc, dst, dcount);
00112 <span class="keywordflow">return</span> c; <span class="comment">/* consumed */</span>
00113 }
00114
00115 <span class="comment">/* the cbuf must be empty because we need the whole buffer to be sure to</span>
00116 <span class="comment"> have enough output space for EVP_{Encrypt,Decrypt}Update */</span>
00117
00118 c = <a class="code" href="utils_8h.html#a0">MIN</a>(src_sz, CODEC_CIPHER_MAX_INPUT);
00119
00120 wr = -1; <span class="comment">/* just used to return an int value */</span>
00121 dbg_err_if(!cc->update(&cc->cipher_ctx, cc->cbuf, &wr, src, c));
00122 cc-><a class="code" href="structcodec__s.html#o4">ccount</a> += wr;
00123
00124 <span class="keywordflow">if</span>(wr == 0)
00125 {
00126 *dcount = 0;
00127 <span class="keywordflow">break</span>; <span class="comment">/* cipher need more input to produce any output */</span>
00128 }
00129 }
00130
00131 dbg_err_if(c == 0 && *dcount == 0);
00132 <span class="keywordflow">return</span> c;
00133 err:
00134 <span class="keywordflow">return</span> -1;
00135 }
00136
00137 <span class="keyword">static</span> <span class="keywordtype">int</span> cipher_free(<a class="code" href="structcodec__s.html">codec_t</a> *codec)
00138 {
00139 <a class="code" href="cipher_8c.html#a2">codec_cipher_t</a> *cc;
00140
00141 nop_return_if (codec == NULL, 0);
00142
00143 cc = (<a class="code" href="cipher_8c.html#a2">codec_cipher_t</a>*)codec;
00144
00145 U_FREE(cc->cbuf);
00146 U_FREE(cc);
00147
00148 <span class="keywordflow">return</span> 0;
00149 }
00150
<a name="l00172"></a><a class="code" href="group__codec__t.html#ga2">00172</a> <span class="keywordtype">int</span> <a class="code" href="group__codec__t.html#ga2">codec_cipher_create</a>(<span class="keywordtype">int</span> op, <span class="keyword">const</span> EVP_CIPHER *cipher,
00173 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *key, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *iv, <a class="code" href="structcodec__s.html">codec_t</a> **pcc)
00174 {
00175 <a class="code" href="cipher_8c.html#a2">codec_cipher_t</a> *cc = NULL;
00176
00177 dbg_return_if (cipher == NULL, ~0);
00178 dbg_return_if (key == NULL, ~0);
00179 <span class="comment">/* iv can be NULL */</span>
00180 dbg_return_if (pcc == NULL, ~0);
00181
00182 cc = u_zalloc(<span class="keyword">sizeof</span>(<a class="code" href="cipher_8c.html#a2">codec_cipher_t</a>));
00183 dbg_err_if(cc == NULL);
00184
00185 cc->codec.<a class="code" href="structcodec__s.html#o0">transform</a> = cipher_transform;
00186 cc->codec.<a class="code" href="structcodec__s.html#o1">flush</a> = cipher_flush;
00187 cc->codec.<a class="code" href="structcodec__s.html#o2">free</a> = cipher_free;
00188
00189 cc->cipher = cipher;
00190
00191 <span class="comment">/* be sure that the cipher stuff is loaded */</span>
00192 EVP_add_cipher(cc->cipher);
00193
00194 EVP_CIPHER_CTX_init(&cc->cipher_ctx);
00195
00196 cc->cbuf_size = <a class="code" href="cipher_8c.html#a9a3">CODEC_CIPHER_MAX_INPUT</a> +
00197 EVP_CIPHER_block_size(cc->cipher) -1;
00198
00199 cc-><a class="code" href="structcodec__s.html#o3">cbuf</a> = u_malloc(cc->cbuf_size);
00200 dbg_err_if(cc->cbuf == NULL);
00201
00202 <span class="keywordflow">switch</span>(op)
00203 {
00204 <span class="keywordflow">case</span> CIPHER_ENCRYPT:
00205 dbg_err_if(!EVP_EncryptInit_ex(&cc->cipher_ctx, cc->cipher, NULL,
00206 key, iv));
00207 cc->update = EVP_EncryptUpdate;
00208 cc->final = EVP_EncryptFinal_ex;
00209 <span class="keywordflow">break</span>;
00210 <span class="keywordflow">case</span> CIPHER_DECRYPT:
00211 dbg_err_if(!EVP_DecryptInit_ex(&cc->cipher_ctx, cc->cipher, NULL,
00212 key, iv));
00213 cc->update = EVP_DecryptUpdate;
00214 cc->final = EVP_DecryptFinal_ex;
00215 <span class="keywordflow">break</span>;
00216 <span class="keywordflow">default</span>:
00217 dbg_err_if(<span class="stringliteral">"bad cipher op"</span>);
00218 }
00219
00220
00221 *pcc = (<a class="code" href="structcodec__s.html">codec_t</a>*)cc;
00222
00223 <span class="keywordflow">return</span> 0;
00224 err:
00225 U_FREE(cc);
00226 <span class="keywordflow">return</span> ~0;
00227 }
00228
</pre></div><hr>
<div>
<div style="text-align:left">
<a href="http://www.koanlogic.com/kl/cont/gb/html/products.html">←Products</a>
</div>
<div style="text-align:center;">
© 2005-2006 - <a href="http://www.koanlogic.com">KoanLogic S.r.l.</a> - All rights reserved
</div>
</div>
</body>
</html>
|