1 module tomcrypt.mac;
2 
3 import core.stdc.config;
4 
5 import tomcrypt.tomcrypt;
6 
7 extern(C) nothrow:
8 
9 version(LTC_HMAC)
10 {
11     struct hmac_state 
12     {
13          hash_state     md;
14          int            hash;
15          hash_state     hashstate;
16          ubyte*         key;
17     }
18 
19     int hmac_init(hmac_state *hmac, int hash, const ubyte* key, c_ulong keylen);
20     int hmac_process(hmac_state *hmac, const ubyte* _in, c_ulong inlen);
21     int hmac_done(hmac_state *hmac, ubyte* _out, c_ulong *outlen);
22     int hmac_test();
23     int hmac_memory(int hash, 
24                     const ubyte* key, c_ulong keylen,
25                     const ubyte* _in,  c_ulong inlen, 
26                           ubyte* _out, c_ulong *outlen);
27     int hmac_memory_multi(int hash, 
28                     const ubyte* key,  c_ulong keylen,
29                           ubyte* _out,  c_ulong *outlen,
30                     const ubyte* _in,   c_ulong inlen, ...);
31     int hmac_file(int hash, const char *fname, const ubyte* key,
32                   c_ulong keylen, 
33                   ubyte* dst, c_ulong *dstlen);
34 }
35 
36 version(LTC_OMAC)
37 {
38 
39     struct omac_state
40     {
41         int                     cipher_idx, 
42                                 buflen,
43                                 blklen;
44         ubyte[MAXBLOCKSIZE]     block,
45                                 prev;
46         ubyte[2][MAXBLOCKSIZE]  Lu;
47         symmetric_key           key;
48     }
49     
50     int omac_init(omac_state *omac, int cipher, const ubyte* key, c_ulong keylen);
51     int omac_process(omac_state *omac, const ubyte* _in, c_ulong inlen);
52     int omac_done(omac_state *omac, ubyte* _out, c_ulong *outlen);
53     int omac_memory(int cipher, 
54                    const ubyte* key, c_ulong keylen,
55                    const ubyte* _in,  c_ulong inlen,
56                          ubyte* _out, c_ulong *outlen);
57     int omac_memory_multi(int cipher, 
58                     const ubyte* key, c_ulong keylen,
59                           ubyte* _out, c_ulong *outlen,
60                     const ubyte* _in,  c_ulong inlen, ...);
61     int omac_file(int cipher, 
62                   const ubyte* key, c_ulong keylen,
63                   const          char *filename, 
64                         ubyte* _out, c_ulong *outlen);
65     int omac_test();
66 } /* LTC_OMAC */
67 
68 version(LTC_PMAC)
69 {
70 
71     struct pmac_state
72     {
73        ubyte[32][MAXBLOCKSIZE]     Ls;            /* L shifted by i bits to the left */
74        ubyte[MAXBLOCKSIZE]         Li,            /* value of Li [current value, we calc from previous recall] */
75                                    Lr,            /* L * x^-1 */
76                                    block,         /* currently accumulated block */
77                                    checksum;      /* current checksum */
78     
79        symmetric_key     key;                     /* scheduled key for cipher */
80        c_ulong           block_index;             /* index # for current block */
81        int               cipher_idx,              /* cipher idx */
82                          block_len,               /* length of block */
83                          buflen;                  /* number of bytes in the buffer */
84     }
85     
86     int pmac_init(pmac_state *pmac, int cipher, const ubyte* key, c_ulong keylen);
87     int pmac_process(pmac_state *pmac, const ubyte* _in, c_ulong inlen);
88     int pmac_done(pmac_state *pmac, ubyte* _out, c_ulong *outlen);
89     
90     int pmac_memory(int cipher, 
91                    const ubyte* key, c_ulong keylen,
92                    const ubyte* msg, c_ulong msglen,
93                          ubyte* _out, c_ulong *outlen);
94     
95     int pmac_memory_multi(int cipher, 
96                     const ubyte* key, c_ulong keylen,
97                           ubyte* _out, c_ulong *outlen,
98                     const ubyte* _in, c_ulong inlen, ...);
99     
100     int pmac_file(int cipher, 
101                  const ubyte* key, c_ulong keylen,
102                  const          char *filename, 
103                        ubyte* _out, c_ulong *outlen);
104     
105     int pmac_test();
106     
107     /* internal functions */
108     int pmac_ntz(c_ulong x);
109     void pmac_shift_xor(pmac_state *pmac);
110 
111 } /* PMAC */
112 
113 version(LTC_EAX_MODE)
114 {
115     version(LTC_OMAC) {}
116     else
117     {
118         pragma(error, "LTC_EAX_MODE requires LTC_OMAC and CTR");
119     }
120     
121     version(LTC_CTR_MODE) {}
122     else
123     {
124         pragma(error, "LTC_EAX_MODE requires LTC_OMAC and CTR");
125     }
126 
127 
128     struct eax_state
129     {
130        ubyte[MAXBLOCKSIZE] N;
131        symmetric_CTR ctr;
132        omac_state    headeromac, ctomac;
133     }
134     
135     int eax_init(eax_state *eax, int cipher, const ubyte* key, c_ulong keylen,
136                  const ubyte* nonce, c_ulong noncelen,
137                  const ubyte* header, c_ulong headerlen);
138     
139     int eax_encrypt(eax_state *eax, const ubyte* pt, ubyte* ct, c_ulong length);
140     int eax_decrypt(eax_state *eax, const ubyte* ct, ubyte* pt, c_ulong length);
141     int eax_addheader(eax_state *eax, const ubyte* header, c_ulong length);
142     int eax_done(eax_state *eax, ubyte* tag, c_ulong *taglen);
143     
144     int eax_encrypt_authenticate_memory(int cipher,
145         const ubyte* key,    c_ulong keylen,
146         const ubyte* nonce,  c_ulong noncelen,
147         const ubyte* header, c_ulong headerlen,
148         const ubyte* pt,     c_ulong ptlen,
149               ubyte* ct,
150               ubyte* tag,    c_ulong *taglen);
151     
152     int eax_decrypt_verify_memory(int cipher,
153         const ubyte* key,    c_ulong keylen,
154         const ubyte* nonce,  c_ulong noncelen,
155         const ubyte* header, c_ulong headerlen,
156         const ubyte* ct,     c_ulong ctlen,
157               ubyte* pt,
158               ubyte* tag,    c_ulong taglen,
159               int           *stat);
160     
161     int eax_test();
162 } /* EAX MODE */
163 
164 version(LTC_OCB_MODE)
165 {
166     struct ocb_state
167     {
168         ubyte[MAXBLOCKSIZE]      L;         /* L value */
169         ubyte[32][MAXBLOCKSIZE]  Ls;        /* L shifted by i bits to the left */
170         ubyte[MAXBLOCKSIZE]      Li,        /* value of Li [current value, we calc from previous recall] */
171                                  Lr,        /* L * x^-1 */
172                                  R,         /* R value */
173                                  checksum;  /* current checksum */
174     
175         symmetric_key       key;                     /* scheduled key for cipher */
176         c_ulong             block_index;             /* index # for current block */
177         int                 cipher,                  /* cipher idx */
178                             block_len;               /* length of block */
179     }
180     
181     int ocb_init(ocb_state *ocb, int cipher, 
182                  const ubyte* key, c_ulong keylen, const ubyte* nonce);
183     
184     int ocb_encrypt(ocb_state *ocb, const ubyte* pt, ubyte* ct);
185     int ocb_decrypt(ocb_state *ocb, const ubyte* ct, ubyte* pt);
186     
187     int ocb_done_encrypt(ocb_state *ocb, 
188                          const ubyte* pt,  c_ulong ptlen,
189                                ubyte* ct, 
190                                ubyte* tag, c_ulong *taglen);
191     
192     int ocb_done_decrypt(ocb_state *ocb, 
193                          const ubyte* ct,  c_ulong ctlen,
194                                ubyte* pt, 
195                          const ubyte* tag, c_ulong taglen, int *stat);
196     
197     int ocb_encrypt_authenticate_memory(int cipher,
198         const ubyte* key,    c_ulong keylen,
199         const ubyte* nonce,  
200         const ubyte* pt,     c_ulong ptlen,
201               ubyte* ct,
202               ubyte* tag,    c_ulong *taglen);
203     
204     int ocb_decrypt_verify_memory(int cipher,
205         const ubyte* key,    c_ulong keylen,
206         const ubyte* nonce,  
207         const ubyte* ct,     c_ulong ctlen,
208               ubyte* pt,
209         const ubyte* tag,    c_ulong taglen,
210               int           *stat);
211     
212     int ocb_test();
213     
214     /* internal functions */
215     void ocb_shift_xor(ocb_state *ocb, ubyte* Z);
216     int ocb_ntz(c_ulong x);
217     int s_ocb_done(ocb_state *ocb, const ubyte* pt, c_ulong ptlen,
218                    ubyte* ct, ubyte* tag, c_ulong *taglen, int mode);
219 
220 } /* LTC_OCB_MODE */
221 
222 version(LTC_CCM_MODE)
223 {
224 
225     enum CCM_ENCRYPT = 0;
226     enum CCM_DECRYPT = 1;
227     
228     int ccm_memory(int cipher,
229         const ubyte* key,    c_ulong keylen,
230         symmetric_key       *uskey,
231         const ubyte* nonce,  c_ulong noncelen,
232         const ubyte* header, c_ulong headerlen,
233               ubyte* pt,     c_ulong ptlen,
234               ubyte* ct,
235               ubyte* tag,    c_ulong *taglen,
236                         int  direction);
237     
238     int ccm_test();
239 
240 } /* LTC_CCM_MODE */
241 
242 version(LRW_MODE)
243 {
244     void gcm_gf_mult(const ubyte* a, const ubyte* b, ubyte* c);
245 }
246 else version(LTC_GCM_MODE)
247 {
248     void gcm_gf_mult(const ubyte* a, const ubyte* b, ubyte* c);
249 }
250 
251 
252 /* table shared between GCM and LRW */
253 //#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
254 version(LTC_GCM_TABLES)
255 {
256     extern __gshared const(ubyte[]) gcm_shift_table;
257 }
258 else version(LRW_TABLES)
259 {
260     extern __gshared const(ubyte[]) gcm_shift_table;
261 }
262 else
263 {
264     version(LTC_FAST)
265     {
266         version(LTC_GCM_MODE)
267         {
268             extern __gshared const(ubyte[]) gcm_shift_table;
269         }
270         else version(LTC_GCM_MODE)
271         {
272             extern __gshared const(ubyte[]) gcm_shift_table;
273         }
274     }
275 }
276 
277 version(LTC_GCM_MODE)
278 {
279     enum GCM_ENCRYPT = 0;
280     enum GCM_DECRYPT = 1;
281     
282     enum LTC_GCM_MODE_IV    = 0;
283     enum LTC_GCM_MODE_AAD   = 1;
284     enum LTC_GCM_MODE_TEXT  = 2;
285     
286     struct gcm_state
287     { 
288        symmetric_key       K;
289        ubyte[16]           H,        /* multiplier */
290                            X,        /* accumulator */
291                            Y,        /* counter */
292                            Y_0,      /* initial counter */
293                            buf;      /* buffer for stuff */
294     
295        int                 cipher,       /* which cipher */
296                            ivmode,       /* Which mode is the IV in? */
297                            mode,         /* mode the GCM code is in */
298                            buflen;       /* length of data in buf */
299     
300        ulong               totlen,       /* 64-bit counter used for IV and AAD */
301                            pttotlen;     /* 64-bit counter for the PT */
302     
303         version(LTC_GCM_TABLES)
304         {
305             
306             version(LTC_GCM_TABLES_SSE2)
307             {
308                 align(16) ubyte[16][256][16]       PC;  /* 16 tables of 8x128 */
309             }
310             else
311             {
312                 ubyte[16][256][16]       PC;  /* 16 tables of 8x128 */
313             }
314         }  
315     }
316     
317     void gcm_mult_h(gcm_state *gcm, ubyte* I);
318     
319     int gcm_init(gcm_state *gcm, int cipher,
320                  const ubyte* key, int keylen);
321     
322     int gcm_reset(gcm_state *gcm);
323     
324     int gcm_add_iv(gcm_state *gcm, 
325                    const ubyte* IV,     c_ulong IVlen);
326     
327     int gcm_add_aad(gcm_state *gcm,
328                    const ubyte* adata,  c_ulong adatalen);
329     
330     int gcm_process(gcm_state *gcm,
331                          ubyte* pt,     c_ulong ptlen,
332                          ubyte* ct,
333                          int direction);
334     
335     int gcm_done(gcm_state *gcm, 
336                          ubyte* tag,    c_ulong *taglen);
337     
338     int gcm_memory(      int           cipher,
339                    const ubyte* key,    c_ulong keylen,
340                    const ubyte* IV,     c_ulong IVlen,
341                    const ubyte* adata,  c_ulong adatalen,
342                          ubyte* pt,     c_ulong ptlen,
343                          ubyte* ct, 
344                          ubyte* tag,    c_ulong *taglen,
345                                    int direction);
346     int gcm_test();
347 
348 } /* LTC_GCM_MODE */
349 
350 version(LTC_PELICAN)
351 {
352 
353     struct pelican_state
354     {
355         symmetric_key K;
356         ubyte[16]     state;
357         int           buflen;
358     }
359     
360     int pelican_init(pelican_state *pelmac, const ubyte* key, c_ulong keylen);
361     int pelican_process(pelican_state *pelmac, const ubyte* _in, c_ulong inlen);
362     int pelican_done(pelican_state *pelmac, ubyte* _out);
363     int pelican_test();
364     
365     int pelican_memory(const ubyte* key, c_ulong keylen,
366                        const ubyte* _in, c_ulong inlen,
367                              ubyte* _out);
368 
369 }
370 
371 version(LTC_XCBC)
372 {
373     /* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
374     enum LTC_XCBC_PURE  = 0x8000UL;
375     
376     struct xcbc_state
377     {
378        ubyte[3][MAXBLOCKSIZE] K;
379        ubyte[MAXBLOCKSIZE]    IV;
380     
381        symmetric_key key;
382     
383                  int cipher,
384                      buflen,
385                      blocksize;
386     }
387     
388     int xcbc_init(xcbc_state *xcbc, int cipher, const ubyte* key, c_ulong keylen);
389     int xcbc_process(xcbc_state *xcbc, const ubyte* _in, c_ulong inlen);
390     int xcbc_done(xcbc_state *xcbc, ubyte* _out, c_ulong *outlen);
391     int xcbc_memory(int cipher, 
392                    const ubyte* key, c_ulong keylen,
393                    const ubyte* _in,  c_ulong inlen,
394                          ubyte* _out, c_ulong *outlen);
395     int xcbc_memory_multi(int cipher, 
396                     const ubyte* key, c_ulong keylen,
397                           ubyte* _out, c_ulong *outlen,
398                     const ubyte* _in,  c_ulong inlen, ...);
399     int xcbc_file(int cipher, 
400                   const ubyte* key, c_ulong keylen,
401                   const          char *filename, 
402                         ubyte* _out, c_ulong *outlen);
403     int xcbc_test();
404 }
405 
406 version(LTC_F9_MODE)
407 {
408 
409     struct f9_state
410     {
411        ubyte[MAXBLOCKSIZE] akey,
412                            ACC,
413                            IV;
414     
415        symmetric_key key;
416     
417                  int cipher,
418                      buflen,
419                      keylen,
420                      blocksize;
421     }
422     
423     int f9_init(f9_state *f9, int cipher, const ubyte* key, c_ulong keylen);
424     int f9_process(f9_state *f9, const ubyte* _in, c_ulong inlen);
425     int f9_done(f9_state *f9, ubyte* _out, c_ulong *outlen);
426     int f9_memory(int cipher, 
427                    const ubyte* key, c_ulong keylen,
428                    const ubyte* _in,  c_ulong inlen,
429                          ubyte* _out, c_ulong *outlen);
430     int f9_memory_multi(int cipher, 
431                     const ubyte* key, c_ulong keylen,
432                           ubyte* _out, c_ulong *outlen,
433                     const ubyte* _in,  c_ulong inlen, ...);
434     int f9_file(int cipher, 
435                   const ubyte* key, c_ulong keylen,
436                   const          char *filename, 
437                         ubyte* _out, c_ulong *outlen);
438     int f9_test();
439 
440 }
441 
442 
443 /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */
444 /* $Revision: 1.23 $ */
445 /* $Date: 2007/05/12 14:37:41 $ */