+++ /dev/null
-/**\r
- * AES.cpp\r
- *\r
- * The Advanced Encryption Standard (AES, aka AES) block cipher,\r
- * designed by J. Daemen and V. Rijmen.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "AES.h"\r
-#include "AES.tab"\r
-\r
-#define FULL_UNROLL\r
-\r
-#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)\r
-\r
-#ifdef _MSC_VER\r
-#define GETWORD(p) SWAP(*((uint *)(p)))\r
-#define PUTWORD(ct, st) { *((uint *)(ct)) = SWAP((st)); }\r
-#else\r
-#define GETWORD(pt) (((uint)(pt)[0] << 24) ^ ((uint)(pt)[1] << 16) ^ ((uint)(pt)[2] << 8) ^ ((uint)(pt)[3]))\r
-#define PUTWORD(ct, st) { (ct)[0] = (byte)((st) >> 24); (ct)[1] = (byte)((st) >> 16); (ct)[2] = (byte)((st) >> 8); (ct)[3] = (byte)(st); }\r
-#endif\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Construction/Destruction\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-AES::AES() {\r
-}\r
-\r
-AES::~AES() {\r
- Nr = 0;\r
- memset(e_sched, 0, sizeof(e_sched));\r
- memset(d_sched, 0, sizeof(d_sched));\r
-}\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Support methods\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-void AES::ExpandKey(const byte *cipherKey, uint keyBits) {\r
- uint *rek = e_sched;\r
- int i = 0;\r
- uint temp;\r
-\r
- rek[0] = GETWORD(cipherKey );\r
- rek[1] = GETWORD(cipherKey + 4);\r
- rek[2] = GETWORD(cipherKey + 8);\r
- rek[3] = GETWORD(cipherKey + 12);\r
- if (keyBits == 128) {\r
- for (;;) {\r
- temp = rek[3];\r
- rek[4] = rek[0] ^\r
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^\r
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^\r
- (Te4[(temp >> 24) ] & 0x000000ff) ^\r
- rcon[i];\r
- rek[5] = rek[1] ^ rek[4];\r
- rek[6] = rek[2] ^ rek[5];\r
- rek[7] = rek[3] ^ rek[6];\r
- if (++i == 10) {\r
- Nr = 10;\r
- return;\r
- }\r
- rek += 4;\r
- }\r
- }\r
- rek[4] = GETWORD(cipherKey + 16);\r
- rek[5] = GETWORD(cipherKey + 20);\r
- if (keyBits == 192) {\r
- for (;;) {\r
- temp = rek[ 5];\r
- rek[ 6] = rek[ 0] ^\r
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^\r
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^\r
- (Te4[(temp >> 24) ] & 0x000000ff) ^\r
- rcon[i];\r
- rek[ 7] = rek[ 1] ^ rek[ 6];\r
- rek[ 8] = rek[ 2] ^ rek[ 7];\r
- rek[ 9] = rek[ 3] ^ rek[ 8];\r
- if (++i == 8) {\r
- Nr = 12;\r
- return;\r
- }\r
- rek[10] = rek[ 4] ^ rek[ 9];\r
- rek[11] = rek[ 5] ^ rek[10];\r
- rek += 6;\r
- }\r
- }\r
- rek[6] = GETWORD(cipherKey + 24);\r
- rek[7] = GETWORD(cipherKey + 28);\r
- if (keyBits == 256) {\r
- for (;;) {\r
- temp = rek[ 7];\r
- rek[ 8] = rek[ 0] ^\r
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^\r
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^\r
- (Te4[(temp >> 24) ] & 0x000000ff) ^\r
- rcon[i];\r
- rek[ 9] = rek[ 1] ^ rek[ 8];\r
- rek[10] = rek[ 2] ^ rek[ 9];\r
- rek[11] = rek[ 3] ^ rek[10];\r
- if (++i == 7) {\r
- Nr = 14;\r
- return;\r
- }\r
- temp = rek[11];\r
- rek[12] = rek[ 4] ^\r
- (Te4[(temp >> 24) ] & 0xff000000) ^\r
- (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^\r
- (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^\r
- (Te4[(temp ) & 0xff] & 0x000000ff);\r
- rek[13] = rek[ 5] ^ rek[12];\r
- rek[14] = rek[ 6] ^ rek[13];\r
- rek[15] = rek[ 7] ^ rek[14];\r
-\r
- rek += 8;\r
- }\r
- }\r
- Nr = 0;\r
-}\r
-\r
-void AES::InvertKey() {\r
- uint *rek = e_sched;\r
- uint *rdk = d_sched;\r
- uint r;\r
-\r
- assert(Nr == 10 || Nr == 12 || Nr == 14);\r
- rek += 4*Nr;\r
- /* apply the inverse MixColumn transform to all round keys but the first and the last: */\r
- memcpy(rdk, rek, 16);\r
- rdk += 4;\r
- rek -= 4;\r
- for (r = 1; r < Nr; r++) {\r
- rdk[0] =\r
- Td0[Te4[(rek[0] >> 24) ] & 0xff] ^\r
- Td1[Te4[(rek[0] >> 16) & 0xff] & 0xff] ^\r
- Td2[Te4[(rek[0] >> 8) & 0xff] & 0xff] ^\r
- Td3[Te4[(rek[0] ) & 0xff] & 0xff];\r
- rdk[1] =\r
- Td0[Te4[(rek[1] >> 24) ] & 0xff] ^\r
- Td1[Te4[(rek[1] >> 16) & 0xff] & 0xff] ^\r
- Td2[Te4[(rek[1] >> 8) & 0xff] & 0xff] ^\r
- Td3[Te4[(rek[1] ) & 0xff] & 0xff];\r
- rdk[2] =\r
- Td0[Te4[(rek[2] >> 24) ] & 0xff] ^\r
- Td1[Te4[(rek[2] >> 16) & 0xff] & 0xff] ^\r
- Td2[Te4[(rek[2] >> 8) & 0xff] & 0xff] ^\r
- Td3[Te4[(rek[2] ) & 0xff] & 0xff];\r
- rdk[3] =\r
- Td0[Te4[(rek[3] >> 24) ] & 0xff] ^\r
- Td1[Te4[(rek[3] >> 16) & 0xff] & 0xff] ^\r
- Td2[Te4[(rek[3] >> 8) & 0xff] & 0xff] ^\r
- Td3[Te4[(rek[3] ) & 0xff] & 0xff];\r
- rdk += 4;\r
- rek -= 4;\r
- }\r
- memcpy(rdk, rek, 16);\r
-}\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Public Interface\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-void AES::makeKey(const byte *cipherKey, uint keySize, uint dir) {\r
- switch (keySize) {\r
- case 16: case 24: case 32:\r
- keySize <<= 3; // key size is now in bits\r
- break;\r
- case 128: case 192: case 256:\r
- break;\r
- default:\r
- assert(keySize == 16 || keySize == 24 || keySize == 32 || keySize == 128 || keySize == 192 || keySize == 256);\r
- }\r
- assert(dir >= DIR_NONE && dir <= DIR_BOTH);\r
- if (dir != DIR_NONE) {\r
- ExpandKey(cipherKey, keySize);\r
- if (dir & DIR_DECRYPT) {\r
- InvertKey();\r
- }\r
- }\r
-}\r
-\r
-void AES::encrypt(const byte *pt, byte *ct) {\r
- uint *rek = e_sched;\r
- uint s0, s1, s2, s3, t0, t1, t2, t3;\r
-#ifndef FULL_UNROLL\r
- int r;\r
-#endif /* ?FULL_UNROLL */\r
-\r
- /*\r
- * map byte array block to cipher state\r
- * and add initial round key:\r
- */\r
- s0 = GETWORD(pt ) ^ rek[0];\r
- s1 = GETWORD(pt + 4) ^ rek[1];\r
- s2 = GETWORD(pt + 8) ^ rek[2];\r
- s3 = GETWORD(pt + 12) ^ rek[3];\r
-#ifdef FULL_UNROLL\r
- /* round 1: */\r
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[ 4];\r
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[ 5];\r
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[ 6];\r
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[ 7];\r
- /* round 2: */\r
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[ 8];\r
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[ 9];\r
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[10];\r
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[11];\r
- /* round 3: */\r
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[12];\r
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[13];\r
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[14];\r
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[15];\r
- /* round 4: */\r
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[16];\r
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[17];\r
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[18];\r
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[19];\r
- /* round 5: */\r
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[20];\r
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[21];\r
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[22];\r
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[23];\r
- /* round 6: */\r
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[24];\r
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[25];\r
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[26];\r
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[27];\r
- /* round 7: */\r
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[28];\r
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[29];\r
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[30];\r
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[31];\r
- /* round 8: */\r
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[32];\r
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[33];\r
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[34];\r
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[35];\r
- /* round 9: */\r
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[36];\r
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[37];\r
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[38];\r
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[39];\r
- if (Nr > 10) {\r
- /* round 10: */\r
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[40];\r
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[41];\r
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[42];\r
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[43];\r
- /* round 11: */\r
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[44];\r
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[45];\r
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[46];\r
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[47];\r
- if (Nr > 12) {\r
- /* round 12: */\r
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[48];\r
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[49];\r
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[50];\r
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[51];\r
- /* round 13: */\r
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[52];\r
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[53];\r
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[54];\r
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[55];\r
- }\r
- }\r
- rek += Nr << 2;\r
-#else /* !FULL_UNROLL */\r
- /*\r
- * Nr - 1 full rounds:\r
- */\r
- r = Nr >> 1;\r
- for (;;) {\r
- t0 =\r
- Te0[(s0 >> 24) ] ^\r
- Te1[(s1 >> 16) & 0xff] ^\r
- Te2[(s2 >> 8) & 0xff] ^\r
- Te3[(s3 ) & 0xff] ^\r
- rek[4];\r
- t1 =\r
- Te0[(s1 >> 24) ] ^\r
- Te1[(s2 >> 16) & 0xff] ^\r
- Te2[(s3 >> 8) & 0xff] ^\r
- Te3[(s0 ) & 0xff] ^\r
- rek[5];\r
- t2 =\r
- Te0[(s2 >> 24) ] ^\r
- Te1[(s3 >> 16) & 0xff] ^\r
- Te2[(s0 >> 8) & 0xff] ^\r
- Te3[(s1 ) & 0xff] ^\r
- rek[6];\r
- t3 =\r
- Te0[(s3 >> 24) ] ^\r
- Te1[(s0 >> 16) & 0xff] ^\r
- Te2[(s1 >> 8) & 0xff] ^\r
- Te3[(s2 ) & 0xff] ^\r
- rek[7];\r
-\r
- rek += 8;\r
- if (--r == 0) {\r
- break;\r
- }\r
-\r
- s0 =\r
- Te0[(t0 >> 24) ] ^\r
- Te1[(t1 >> 16) & 0xff] ^\r
- Te2[(t2 >> 8) & 0xff] ^\r
- Te3[(t3 ) & 0xff] ^\r
- rek[0];\r
- s1 =\r
- Te0[(t1 >> 24) ] ^\r
- Te1[(t2 >> 16) & 0xff] ^\r
- Te2[(t3 >> 8) & 0xff] ^\r
- Te3[(t0 ) & 0xff] ^\r
- rek[1];\r
- s2 =\r
- Te0[(t2 >> 24) ] ^\r
- Te1[(t3 >> 16) & 0xff] ^\r
- Te2[(t0 >> 8) & 0xff] ^\r
- Te3[(t1 ) & 0xff] ^\r
- rek[2];\r
- s3 =\r
- Te0[(t3 >> 24) ] ^\r
- Te1[(t0 >> 16) & 0xff] ^\r
- Te2[(t1 >> 8) & 0xff] ^\r
- Te3[(t2 ) & 0xff] ^\r
- rek[3];\r
- }\r
-#endif /* ?FULL_UNROLL */\r
- /*\r
- * apply last round and\r
- * map cipher state to byte array block:\r
- */\r
- s0 =\r
- (Te4[(t0 >> 24) ] & 0xff000000) ^\r
- (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Te4[(t3 ) & 0xff] & 0x000000ff) ^\r
- rek[0];\r
- PUTWORD(ct , s0);\r
- s1 =\r
- (Te4[(t1 >> 24) ] & 0xff000000) ^\r
- (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Te4[(t0 ) & 0xff] & 0x000000ff) ^\r
- rek[1];\r
- PUTWORD(ct + 4, s1);\r
- s2 =\r
- (Te4[(t2 >> 24) ] & 0xff000000) ^\r
- (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Te4[(t1 ) & 0xff] & 0x000000ff) ^\r
- rek[2];\r
- PUTWORD(ct + 8, s2);\r
- s3 =\r
- (Te4[(t3 >> 24) ] & 0xff000000) ^\r
- (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Te4[(t2 ) & 0xff] & 0x000000ff) ^\r
- rek[3];\r
- PUTWORD(ct + 12, s3);\r
-}\r
-\r
-void AES::decrypt(const byte *ct, byte *pt) {\r
- uint *rdk = d_sched;\r
- uint s0, s1, s2, s3, t0, t1, t2, t3;\r
-#ifndef FULL_UNROLL\r
- int r;\r
-#endif /* ?FULL_UNROLL */\r
-\r
- /*\r
- * map byte array block to cipher state\r
- * and add initial round key:\r
- */\r
- s0 = GETWORD(ct ) ^ rdk[0];\r
- s1 = GETWORD(ct + 4) ^ rdk[1];\r
- s2 = GETWORD(ct + 8) ^ rdk[2];\r
- s3 = GETWORD(ct + 12) ^ rdk[3];\r
-#ifdef FULL_UNROLL\r
- /* round 1: */\r
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[ 4];\r
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[ 5];\r
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[ 6];\r
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[ 7];\r
- /* round 2: */\r
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[ 8];\r
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[ 9];\r
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[10];\r
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[11];\r
- /* round 3: */\r
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[12];\r
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[13];\r
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[14];\r
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[15];\r
- /* round 4: */\r
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[16];\r
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[17];\r
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[18];\r
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[19];\r
- /* round 5: */\r
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[20];\r
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[21];\r
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[22];\r
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[23];\r
- /* round 6: */\r
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[24];\r
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[25];\r
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[26];\r
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[27];\r
- /* round 7: */\r
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[28];\r
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[29];\r
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[30];\r
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[31];\r
- /* round 8: */\r
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[32];\r
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[33];\r
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[34];\r
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[35];\r
- /* round 9: */\r
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[36];\r
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[37];\r
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[38];\r
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[39];\r
- if (Nr > 10) {\r
- /* round 10: */\r
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[40];\r
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[41];\r
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[42];\r
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[43];\r
- /* round 11: */\r
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[44];\r
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[45];\r
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[46];\r
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[47];\r
- if (Nr > 12) {\r
- /* round 12: */\r
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[48];\r
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[49];\r
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[50];\r
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[51];\r
- /* round 13: */\r
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[52];\r
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[53];\r
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[54];\r
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[55];\r
- }\r
- }\r
- rdk += Nr << 2;\r
-#else /* !FULL_UNROLL */\r
- /*\r
- * Nr - 1 full rounds:\r
- */\r
- r = Nr >> 1;\r
- for (;;) {\r
- t0 =\r
- Td0[(s0 >> 24) ] ^\r
- Td1[(s3 >> 16) & 0xff] ^\r
- Td2[(s2 >> 8) & 0xff] ^\r
- Td3[(s1 ) & 0xff] ^\r
- rdk[4];\r
- t1 =\r
- Td0[(s1 >> 24) ] ^\r
- Td1[(s0 >> 16) & 0xff] ^\r
- Td2[(s3 >> 8) & 0xff] ^\r
- Td3[(s2 ) & 0xff] ^\r
- rdk[5];\r
- t2 =\r
- Td0[(s2 >> 24) ] ^\r
- Td1[(s1 >> 16) & 0xff] ^\r
- Td2[(s0 >> 8) & 0xff] ^\r
- Td3[(s3 ) & 0xff] ^\r
- rdk[6];\r
- t3 =\r
- Td0[(s3 >> 24) ] ^\r
- Td1[(s2 >> 16) & 0xff] ^\r
- Td2[(s1 >> 8) & 0xff] ^\r
- Td3[(s0 ) & 0xff] ^\r
- rdk[7];\r
-\r
- rdk += 8;\r
- if (--r == 0) {\r
- break;\r
- }\r
-\r
- s0 =\r
- Td0[(t0 >> 24) ] ^\r
- Td1[(t3 >> 16) & 0xff] ^\r
- Td2[(t2 >> 8) & 0xff] ^\r
- Td3[(t1 ) & 0xff] ^\r
- rdk[0];\r
- s1 =\r
- Td0[(t1 >> 24) ] ^\r
- Td1[(t0 >> 16) & 0xff] ^\r
- Td2[(t3 >> 8) & 0xff] ^\r
- Td3[(t2 ) & 0xff] ^\r
- rdk[1];\r
- s2 =\r
- Td0[(t2 >> 24) ] ^\r
- Td1[(t1 >> 16) & 0xff] ^\r
- Td2[(t0 >> 8) & 0xff] ^\r
- Td3[(t3 ) & 0xff] ^\r
- rdk[2];\r
- s3 =\r
- Td0[(t3 >> 24) ] ^\r
- Td1[(t2 >> 16) & 0xff] ^\r
- Td2[(t1 >> 8) & 0xff] ^\r
- Td3[(t0 ) & 0xff] ^\r
- rdk[3];\r
- }\r
-#endif /* ?FULL_UNROLL */\r
- /*\r
- * apply last round and\r
- * map cipher state to byte array block:\r
- */\r
- s0 =\r
- (Td4[(t0 >> 24) ] & 0xff000000) ^\r
- (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Td4[(t1 ) & 0xff] & 0x000000ff) ^\r
- rdk[0];\r
- PUTWORD(pt , s0);\r
- s1 =\r
- (Td4[(t1 >> 24) ] & 0xff000000) ^\r
- (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Td4[(t2 ) & 0xff] & 0x000000ff) ^\r
- rdk[1];\r
- PUTWORD(pt + 4, s1);\r
- s2 =\r
- (Td4[(t2 >> 24) ] & 0xff000000) ^\r
- (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Td4[(t3 ) & 0xff] & 0x000000ff) ^\r
- rdk[2];\r
- PUTWORD(pt + 8, s2);\r
- s3 =\r
- (Td4[(t3 >> 24) ] & 0xff000000) ^\r
- (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^\r
- (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^\r
- (Td4[(t0 ) & 0xff] & 0x000000ff) ^\r
- rdk[3];\r
- PUTWORD(pt + 12, s3);\r
-}\r
-\r
+++ /dev/null
-/**\r
- * AES.h\r
- *\r
- * The Advanced Encryption Standard (AES, aka AES) block cipher,\r
- * designed by J. Daemen and V. Rijmen.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __AES_H\r
-#define __AES_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(AES_H, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char byte;\r
-typedef unsigned long uint; /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-#ifndef AES_BLOCKBITS\r
-#define AES_BLOCKBITS 128\r
-#endif\r
-#if AES_BLOCKBITS != 128\r
-#error "AES_BLOCKBITS must be 128"\r
-#endif\r
-\r
-#ifndef AES_BLOCKSIZE\r
-#define AES_BLOCKSIZE 16 /* bytes */\r
-#endif\r
-#if AES_BLOCKSIZE != 16\r
-#error "AES_BLOCKSIZE must be 16"\r
-#endif\r
-\r
-#ifndef AES_MINKEYBITS\r
-#define AES_MINKEYBITS 128\r
-#endif\r
-#if AES_MINKEYBITS != 128\r
-#error "AES_MINKEYBITS must be 128"\r
-#endif\r
-\r
-#ifndef AES_MINKEYSIZE\r
-#define AES_MINKEYSIZE 16 /* bytes */\r
-#endif\r
-#if AES_MINKEYSIZE != 16\r
-#error "AES_MINKEYSIZE must be 16"\r
-#endif\r
-\r
-#ifndef AES_MAXKEYBITS\r
-#define AES_MAXKEYBITS 256\r
-#endif\r
-#if AES_MAXKEYBITS != 256\r
-#error "AES_MAXKEYBITS must be 256"\r
-#endif\r
-\r
-#ifndef AES_MAXKEYSIZE\r
-#define AES_MAXKEYSIZE 32 /* bytes */\r
-#endif\r
-#if AES_MAXKEYSIZE != 32\r
-#error "AES_MAXKEYSIZE must be 32"\r
-#endif\r
-\r
-#define MAXKC (AES_MAXKEYBITS/32)\r
-#define MAXKB (AES_MAXKEYBITS/8)\r
-#define MAXNR 14\r
-\r
-class AES: public BlockCipher {\r
-public:\r
-\r
- AES();\r
- virtual ~AES();\r
-\r
- /**\r
- * Block size in bits.\r
- */\r
- inline uint blockBits() const {\r
- return AES_BLOCKBITS;\r
- }\r
-\r
- /**\r
- * Block size in bytes.\r
- */\r
- inline uint blockSize() const {\r
- return AES_BLOCKSIZE;\r
- }\r
-\r
- /**\r
- * Key size in bits.\r
- */\r
- inline uint keyBits() const {\r
- return (Nr - 6) << 5;\r
- }\r
-\r
- /**\r
- * Key size in bytes.\r
- */\r
- inline uint keySize() const {\r
- return (Nr - 6) << 2;\r
- }\r
-\r
- void makeKey(const byte *cipherKey, uint keyBits, uint dir);\r
-\r
- void encrypt(const byte *pt, byte *ct);\r
-\r
- void decrypt(const byte *ct, byte *pt);\r
-\r
-private:\r
- // static void Initialize();\r
- void ExpandKey(const byte *cipherKey, uint keyBits);\r
- void InvertKey();\r
- uint Nr;\r
- uint e_sched[4*(MAXNR + 1)];\r
- uint d_sched[4*(MAXNR + 1)];\r
-};\r
-\r
-#endif /* __AES_H */\r
-\r
+++ /dev/null
-/**\r
- * BlockCipher.h\r
- *\r
- * A simple abstraction for the basic functionality of a block cipher engine.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __BLOCKCIPHER_H\r
-#define __BLOCKCIPHER_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(BlockCipher_h, "$Id$")\r
-\r
-#include "/usr/include/sys/types.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char byte;\r
-//typedef unsigned long uint; /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-#define DIR_NONE 0\r
-#define DIR_ENCRYPT 1\r
-#define DIR_DECRYPT 2\r
-#define DIR_BOTH (DIR_ENCRYPT | DIR_DECRYPT) /* both directions */\r
-\r
-class BlockCipher {\r
-public:\r
-\r
- /**\r
- * Cipher's block size in bits.\r
- */\r
- virtual uint blockBits() const = 0;\r
-\r
- /**\r
- * Cipher's block size in bytes.\r
- */\r
- virtual uint blockSize() const = 0;\r
-\r
- /**\r
- * Cipher's key size in bits.\r
- */\r
- virtual uint keyBits() const = 0;\r
-\r
- /**\r
- * Cipher's key size in bytes.\r
- */\r
- virtual uint keySize() const = 0;\r
-\r
- /**\r
- * Setup the key schedule for encryption, decryption, or both.\r
- *\r
- * @param cipherKey the cipher key.\r
- * @param keyBits size of the cipher key in bits.\r
- * @param direction cipher direction (DIR_ENCRYPT, DIR_DECRYPT, or DIR_BOTH).\r
- */\r
- virtual void makeKey(const byte *cipherKey, uint keyBits, uint dir) = 0;\r
-\r
- /**\r
- * Encrypt exactly one block of plaintext.\r
- *\r
- * @param pt plaintext block.\r
- * @param ct ciphertext block.\r
- */\r
- virtual void encrypt(const byte *pt, byte *ct) = 0;\r
-\r
- /**\r
- * Decrypt exactly one block of ciphertext.\r
- *\r
- * @param ct ciphertext block.\r
- * @param pt plaintext block.\r
- */\r
- virtual void decrypt(const byte *ct, byte *pt) = 0;\r
-\r
-};\r
-\r
-#endif /* __BLOCKCIPHER_H */\r
+++ /dev/null
-/*\r
- * CTR.cpp\r
- *\r
- * The counter (CTR) mode of operation for block ciphers.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "CTR.h"\r
-\r
-CTR::CTR(BlockCipher* E) {\r
- this->E = E;\r
- block_size = E->blockSize();\r
- N = (byte *)calloc(block_size, 1);\r
- S = (byte *)calloc(block_size, 1);\r
- s = 0;\r
-}\r
-\r
-CTR::~CTR() {\r
- memset(N, (byte)0, block_size); free(N);\r
- memset(S, (byte)0, block_size); free(S);\r
-}\r
-\r
-void CTR::init(const byte* N) {\r
- // initialize nonce:\r
- memcpy(this->N, N, block_size);\r
- E->encrypt(N, S); // S = E_K(N)\r
- s = block_size;\r
-}\r
-\r
-void CTR::update(const byte* M, uint m, byte* C) {\r
- uint i = block_size - s;\r
- uint j = 0;\r
- while (m >= s) {\r
- for (uint b = 0; b < s; b++) {\r
- C[j + b] = (byte)(M[j + b] ^ S[i + b]);\r
- }\r
- // proceed to the next block:\r
- m -= s;\r
- j += s;\r
- // increment the nonce:\r
- for (uint n = block_size - 1; n >= 0; n--) {\r
- if ((++N[n] & 0xff) != 0) {\r
- break;\r
- }\r
- }\r
- E->encrypt(N, S);\r
- s = block_size;\r
- i = 0;\r
- }\r
- //assert(m < s);\r
- // process remaining chunk (m bytes):\r
- for (uint b = 0; b < m; b++) {\r
- C[j + b] = (byte)(M[j + b] ^ S[i + b]);\r
- }\r
- s -= m;\r
- //assert(0 < s && s <= block_size);\r
-}\r
-\r
+++ /dev/null
-/*\r
- * CTR.h\r
- *\r
- * The counter (CTR) mode of operation for block ciphers.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __CTR_H\r
-#define __CTR_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(CTR_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char byte;\r
-typedef unsigned long uint; /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-class CTR {\r
-public:\r
-\r
- CTR(BlockCipher* E);\r
- virtual ~CTR();\r
-\r
- /**\r
- * Start encrypting/decrypting a message using a given nonce.\r
- *\r
- * @param N the normalized nonce (initial counter value)\r
- */\r
- void init(const byte* N);\r
-\r
- /**\r
- * Either encrypt or decrypt a message chunk.\r
- *\r
- * @param M message chunk\r
- * @param m its length in bytes\r
- * @param C the resulting encrypted/decrypted message chunk\r
- */\r
- void update(const byte* M, uint m, byte* C);\r
-\r
-private:\r
- BlockCipher *E; // block cipher context\r
- uint block_size;\r
- byte* N; // CTR counter (block_size bytes)\r
- byte* S; // CTR mask (block_size bytes)\r
- uint s; // available mask bytes on S\r
-};\r
-\r
-#endif /* __CTR_H */\r
-\r
+++ /dev/null
-/*\r
- * EAX.cpp\r
- *\r
- * The EAX authenticated encryption mode of operation,\r
- * designed by M. Bellare, P. Rogaway and D. Wagner.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "EAX.h"\r
-\r
-EAX::EAX() {\r
- _E = 0; // block cipher context\r
- tag_size = 0;\r
- block_size = 0;\r
- t_n = 0; // [t]_n\r
- _C = 0; // CTR context\r
- nt = 0;\r
- ht = 0;\r
- mt = 0;\r
-}\r
-\r
-/*********************************************************************\r
- * Calls common to incremental and non-incremental API\r
- ********************************************************************/\r
-\r
-void EAX::initialize(const byte* K, uint k, uint t, BlockCipher* E) {\r
- if (E == 0) {\r
- throw "Invalid cipher";\r
- }\r
- if (K == 0) {\r
- throw "Invalid key size";\r
- }\r
- if (t > E->blockSize()) {\r
- throw "Invalid tag size";\r
- }\r
- _E = E;\r
- _E->makeKey(K, k, DIR_ENCRYPT);\r
- _C = new CTR(_E);\r
- tag_size = t;\r
- block_size = _E->blockSize();\r
- t_n = (byte *)calloc(block_size, 1);\r
- nt = (byte *)calloc(block_size, 1);\r
- ht = (byte *)calloc(block_size, 1);\r
- mt = (byte *)calloc(block_size, 1);\r
-}\r
-\r
-/**\r
- * Session is over; destroy all key material and cleanup!\r
- */\r
-EAX::~EAX() {\r
- if (_E != 0) {\r
- t_n[block_size - 1] = 0;\r
- delete _C;\r
- memset(nt, (byte)0, block_size);\r
- memset(ht, (byte)0, block_size);\r
- memset(mt, (byte)0, block_size);\r
- }\r
-}\r
-\r
-/**\r
- * Supply a message header. The header "grows" with each call\r
- * until a eax_provide_header() call is made that follows a\r
- * eax_encrypt(), eax_decrypt(), eax_provide_plaintext(),\r
- * eax_provide_ciphertext() or eax_compute_plaintext() call.\r
- * That starts reinitializes the header.\r
- */\r
-void EAX::provideHeader(const byte* H, uint h) {\r
- if (H == 0 && h > 0) {\r
- throw "Invalid header";\r
- }\r
- _H.update(H, h);\r
-}\r
-\r
-\r
-/*********************************************************************\r
- * All-in-one, non-incremental interface\r
- ********************************************************************/\r
-\r
-/**\r
- * Encrypt the given message with the given key, nonce and header.\r
- * Specify the header (if nonempty) with eax_provide_header().\r
- */\r
-void EAX::encrypt(\r
- const byte* N, // the nonce and\r
- uint n, // its length (in bytes), and\r
- const byte* M, // the plaintext and\r
- uint m, // its length (in bytes).\r
- byte* C, // The m-byte ciphertext\r
- byte* T) { // and the tag T are returned.\r
- provideNonce(N, n);\r
- computeCiphertext(M, m, C);\r
- if (T != 0) {\r
- computeTag(T);\r
- }\r
-}\r
-\r
-/**\r
- * Decrypt the given ciphertext with the given key, nonce and header.\r
- * Specify the header (if nonempty) with eax_provide_header().\r
- * Returns 1 for a valid ciphertext, 0 for an invalid ciphertext and for invalid or missing parameters.\r
- */\r
-bool EAX::decrypt(\r
- const byte* N, // the nonce and\r
- uint n, // its length (in bytes), and\r
- const byte* C, // the ciphertext and\r
- uint c, // its length (in bytes), and\r
- const byte* T, // the tag.\r
- byte* P) { // if valid, return the c-byte plaintext.\r
- provideNonce(N, n);\r
- provideCiphertext(C, c);\r
- if (checkTag(T)) {\r
- computePlaintext(C, c, P);\r
- return true;\r
- } else {\r
- return false;\r
- }\r
-}\r
-\r
-\r
-/*********************************************************************\r
- * Incremental interface\r
- ********************************************************************/\r
-\r
-/**\r
- * Provide a nonce. For encryption, do this before calling\r
- * eax_compute_ciphertext() and eax_compute_tag();\r
- * for decryption, do this before calling\r
- * eax_provide_ciphertext(), eax_check_tag, or eax_compute_plaintext().\r
- */\r
-void EAX::provideNonce(const byte* N, uint n) {\r
- if (N == 0 && n > 0) {\r
- throw "Invalid nonce";\r
- }\r
- // nonce OMAC:\r
- t_n[block_size - 1] = 0;\r
- _N.init(_E);\r
- _N.update(t_n, block_size);\r
- _N.update(N, n);\r
- _N.final(nt);\r
- _C->init(nt); // N <- OMAC_K^0(N)\r
- memset(nt, (byte)0, block_size);\r
- // header OMAC:\r
- t_n[block_size - 1] = 1;\r
- _H.init(_E);\r
- _H.update(t_n, block_size);\r
- // message OMAC:\r
- t_n[block_size - 1] = 2;\r
- _M.init(_E);\r
- _M.update(t_n, block_size);\r
-}\r
-\r
-/**\r
- * Encrypt a message or a part of a message.\r
- * The nonce needs already to have been\r
- * specified by a call to eax_provide_nonce().\r
- */\r
-void EAX::computeCiphertext(const byte* M, uint m, byte* C) {\r
- if (M == 0 && m > 0 ||\r
- C == 0) {\r
- throw "Invalid buffer(s)";\r
- }\r
- _C->update(M, m, C);\r
- _M.update(C, m);\r
-}\r
-\r
-/**\r
- * Message and header finished: compute the authentication tag that is a part\r
- * of the complete ciphertext.\r
- */\r
-void EAX::computeTag(byte* T) { // compute the tag T.\r
- if (T == 0 && tag_size > 0) {\r
- throw "Invalid tag";\r
- }\r
- //assert(M.t < block_size); // at least [t]_n must have been provided\r
- _N.final(nt);\r
- _H.final(ht);\r
- _M.final(mt);\r
- for (uint i = 0; i < tag_size; i++) {\r
- T[i] = (byte)(nt[i] ^ ht[i] ^ mt[i]);\r
- }\r
-}\r
-\r
-/**\r
- * Supply the ciphertext, or the next piece of ciphertext.\r
- * This is used to check for the subsequent authenticity check eax_check_tag().\r
- */\r
-void EAX::provideCiphertext(const byte* C, uint c) {\r
- if (C == 0 && c > 0) {\r
- throw "Invalid ciphertext";\r
- }\r
- _M.update(C, c);\r
-}\r
-\r
-/**\r
- * The nonce, ciphertext and header have all been fully provided; check if\r
- * they are valid for the given tag.\r
- * Returns true for a valid ciphertext, false for an invalid ciphertext\r
- * (in which case plaintext/ciphertext might be zeroized as well).\r
- */\r
-bool EAX::checkTag(const byte* T) {\r
- if (T == 0 && tag_size > 0) {\r
- throw "Invalid tag";\r
- }\r
- //assert(M.t < block_size); // at least [t]_n must have been provided\r
- _N.final(nt);\r
- _H.final(ht);\r
- _M.final(mt);\r
- for (uint i = 0; i < tag_size; i++) {\r
- if (T[i] != (byte)(nt[i] ^ ht[i] ^ mt[i])) {\r
- return false;\r
- }\r
- }\r
- return true;\r
-}\r
-\r
-/**\r
- * Recover the plaintext from the provided ciphertext.\r
- * A call to eax_provide_nonce() needs to precede this call.\r
- * The caller is responsible for separately checking if the ciphertext is valid.\r
- * Normally this would be done before computing the plaintext with\r
- * eax_compute_plaintext().\r
- */\r
-void EAX::computePlaintext(const byte* C, uint c, byte* P) {\r
- if (C == 0 && c > 0 ||\r
- P == 0) {\r
- throw "Invalid buffer(s)";\r
- }\r
- _C->update(C, c, P);\r
-}\r
-\r
+++ /dev/null
-/*\r
- * EAX.h\r
- *\r
- * The EAX authenticated encryption mode of operation,\r
- * designed by M. Bellare, P. Rogaway and D. Wagner.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __EAX_H\r
-#define __EAX_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(EAX_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-#include "OMAC.h"\r
-#include "CTR.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char byte;\r
-typedef unsigned long uint; /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-class EAX {\r
-public:\r
-\r
- EAX();\r
-\r
- /**\r
- * Key and parameter setup to init a EAX context data structure.\r
- */\r
- void initialize(const byte* K, uint k, uint t, BlockCipher* E);\r
-\r
- /**\r
- * Session is over; destroy all key material and cleanup!\r
- */\r
- virtual ~EAX();\r
-\r
- /*********************************************************************\r
- * Calls common to incremental and non-incremental API\r
- ********************************************************************/\r
-\r
- /**\r
- * Supply a message header. The header "grows" with each call\r
- * until a eax_provide_header() call is made that follows a\r
- * eax_encrypt(), eax_decrypt(), eax_provide_plaintext(),\r
- * eax_provide_ciphertext() or eax_compute_plaintext() call.\r
- * That starts reinitializes the header.\r
- */\r
- void provideHeader(const byte* H, uint h);\r
-\r
-\r
- /*********************************************************************\r
- * All-in-one, non-incremental interface\r
- ********************************************************************/\r
-\r
- /**\r
- * Encrypt the given message with the given key, nonce and header.\r
- * Specify the header (if nonempty) with eax_provide_header().\r
- */\r
- void encrypt(\r
- const byte* N, // the nonce and\r
- uint n, // its length (in bytes), and\r
- const byte* M, // the plaintext and\r
- uint m, // its length (in bytes).\r
- byte* C, // The m-byte ciphertext\r
- byte* T);\r
-\r
- /**\r
- * Decrypt the given ciphertext with the given key, nonce and header.\r
- * Specify the header (if nonempty) with eax_provide_header().\r
- * Returns 1 for a valid ciphertext, 0 for an invalid ciphertext and for invalid or missing parameters.\r
- */\r
- bool decrypt(\r
- const byte* N, // the nonce and\r
- uint n, // its length (in bytes), and\r
- const byte* C, // the ciphertext and\r
- uint c, // its length (in bytes), and\r
- const byte* T, // the tag.\r
- byte* P);\r
-\r
-\r
- /*********************************************************************\r
- * Incremental interface\r
- ********************************************************************/\r
-\r
- /**\r
- * Provide a nonce. For encryption, do this before calling\r
- * eax_compute_ciphertext() and eax_compute_tag();\r
- * for decryption, do this before calling\r
- * eax_provide_ciphertext(), eax_check_tag, or eax_compute_plaintext().\r
- */\r
- void provideNonce(const byte* N, uint n);\r
-\r
- /**\r
- * Encrypt a message or a part of a message.\r
- * The nonce needs already to have been\r
- * specified by a call to eax_provide_nonce().\r
- */\r
- void computeCiphertext(const byte* M, uint m, byte* C);\r
-\r
- /**\r
- * Message and header finished: compute the authentication tag that is a part\r
- * of the complete ciphertext.\r
- */\r
- void computeTag(byte* T);\r
-\r
- /**\r
- * Supply the ciphertext, or the next piece of ciphertext.\r
- * This is used to check for the subsequent authenticity check eax_check_tag().\r
- */\r
- void provideCiphertext(const byte* C, uint c);\r
-\r
- /**\r
- * The nonce, ciphertext and header have all been fully provided; check if\r
- * they are valid for the given tag.\r
- * Returns true for a valid ciphertext, false for an invalid ciphertext\r
- * (in which case plaintext/ciphertext might be zeroized as well).\r
- */\r
- bool checkTag(const byte* T);\r
-\r
- /**\r
- * Recover the plaintext from the provided ciphertext.\r
- * A call to eax_provide_nonce() needs to precede this call.\r
- * The caller is responsible for separately checking if the ciphertext is valid.\r
- * Normally this would be done before computing the plaintext with\r
- * eax_compute_plaintext().\r
- */\r
- void computePlaintext(const byte* C, uint c, byte* P);\r
-\r
-private:\r
- BlockCipher* _E;// block cipher context\r
- uint tag_size;\r
- uint block_size;\r
- byte* t_n; // [t]_n\r
- OMAC _N; // nonce OMAC\r
- OMAC _H; // header OMAC\r
- OMAC _M; // message OMAC\r
- CTR* _C; // CTR context\r
- byte* nt;\r
- byte* ht;\r
- byte* mt;\r
-};\r
-\r
-#endif /* __EAX_H */\r
-\r
+++ /dev/null
-#
-# $Id$
-#
-
-TARGET = rlm_eap_psk
-SRCS = rlm_eap_psk.cpp eap_psk.cpp eap_psk_ssm.cpp AES.cpp OMAC.cpp CTR.cpp EAX.cpp SOBMMO.cpp userinfo.c
-HEADERS = eap_psk.h eap_psk_ssm.h AES.h OMAC.h CTR.h EAX.h BlockCipher.h SOBMMO.h userinfo.h
-RLM_CFLAGS = $(INCLTDL) -I../.. -I../../libeap
-RLM_LIBS = -lstdc++
-RLM_INSTALL =
-
-RLM_DIR=../../
-include ${RLM_DIR}../rules.mak
-
-$(LT_OBJS): $(HEADERS)
+++ /dev/null
-/*\r
- * OMAC.cpp\r
- *\r
- * The One-key CBC MAC (OMAC) message authentication code,\r
- * designed by T. Iwata and K. Kurosawa.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "OMAC.h"\r
-\r
-OMAC::OMAC() {\r
- _E = 0;\r
- block_size = 0;\r
- t = 0;\r
- mask = 0;\r
- ready = 0;\r
- memset(L, (byte)0, sizeof(L));\r
- memset(T, (byte)0, sizeof(L));\r
-}\r
-\r
-OMAC::~OMAC() {\r
- _E = 0;\r
- block_size = 0;\r
- t = 0;\r
- mask = 0;\r
- ready = 0;\r
- memset(L, (byte)0, sizeof(L));\r
- memset(T, (byte)0, sizeof(L));\r
-}\r
-\r
-void OMAC::init(BlockCipher* E) {\r
- if (E == 0) {\r
- throw "Invalid block cipher";\r
- }\r
- _E = E;\r
- t = block_size = _E->blockSize();\r
- if (block_size != 16 && block_size != 8) {\r
- throw "Block size not supported";\r
- }\r
- mask = (block_size == 16) ? 0x87 : 0x1B;\r
- // compute padding mask:\r
- memset(L, (byte)0, block_size);\r
- _E->encrypt(L, L); // L = E_K(0^n)\r
- uint c = L[0] & 0x80; // carry\r
- for (uint b = 0; b < block_size - 1; b++) {\r
- L[b] = (byte)((L[b] << 1) | ((L[b + 1] & 0xff) >> 7));\r
- }\r
- L[block_size - 1] = (byte)((L[block_size - 1] << 1) ^ (c != 0 ? mask : 0)); // B = 2L\r
- // initialize tag accumulator\r
- memset(T, (byte)0, block_size);\r
- ready = 0;\r
-}\r
-\r
-void OMAC::update(const byte* M, uint m) {\r
- if (_E == 0) {\r
- throw "OMAC computation not initialized";\r
- }\r
- uint i = block_size - t;\r
- uint j = 0;\r
- while (m > t) { // N.B. m is strictly larger than t!\r
- // complete tag block:\r
- for (uint b = 0; b < t; b++) {\r
- T[i + b] ^= M[j + b];\r
- }\r
- _E->encrypt(T, T); // since there is more data, no padding applies\r
- // proceed to the next block:\r
- m -= t;\r
- j += t;\r
- t = block_size;\r
- i = 0;\r
- //assert(m > 0);\r
- }\r
- // process remaining chunk (m bytes):\r
- for (uint b = 0; b < m; b++) {\r
- T[i + b] ^= M[j + b];\r
- }\r
- t -= m;\r
- //assert(m == 0 || t < block_size); // m == 0 here only occurs if m == 0 from the very beginning\r
-}\r
-\r
-void OMAC::final(byte* tag) {\r
- if (_E != 0) {\r
- // compute padding:\r
- if (t > 0) {\r
- // compute special padding mask:\r
- uint c = L[0] & 0x80; // carry\r
- for (uint b = 0; b < block_size - 1; b++) {\r
- L[b] = (byte)((L[b] << 1) | ((L[b + 1] & 0xff) >> 7));\r
- }\r
- L[block_size - 1] = (byte)((L[block_size - 1] << 1) ^ (c != 0 ? mask : 0)); // P = 4L\r
- // pad incomplete block:\r
- T[block_size - t] ^= 0x80; // padding toggle\r
- t = 0;\r
- }\r
- for (uint b = 0; b < block_size; b++) {\r
- T[b] ^= L[b];\r
- }\r
- _E->encrypt(T, T); // T contains the complete tag\r
- ready = 1; // OMAC tag available\r
- _E = 0; // OMAC computation is complete; context no longer initialized\r
- } else if (!ready) {\r
- throw "OMAC computation not initialized";\r
- }\r
- memcpy(tag, T, block_size);\r
-}\r
-\r
+++ /dev/null
-/*\r
- * OMAC.h\r
- *\r
- * The One-key CBC MAC (OMAC) message authentication code,\r
- * designed by T. Iwata and K. Kurosawa.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __OMAC_H\r
-#define __OMAC_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(OMAC_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char byte;\r
-typedef unsigned long uint; /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-#define OMAC_MAXBLOCKSIZE 16\r
-\r
-class OMAC {\r
-public:\r
-\r
- OMAC();\r
-\r
- virtual ~OMAC();\r
-\r
- /**\r
- * Start computing an OMAC tag by selecting the underlying block cipher.\r
- *\r
- * @param E block cipher underlying OMAC computation.\r
- * CAVEAT: in the current implementation the block size\r
- * must be either 16 or 8.\r
- */\r
- void init(BlockCipher* E);\r
-\r
- /**\r
- * Update the OMAC tag computation with a message chunk.\r
- *\r
- * @param M message chunk\r
- * @param m its length in bytes\r
- */\r
- void update(const byte* M, uint m);\r
-\r
- /**\r
- * Complete the computation of the OMAC tag, or simply\r
- * get the finished OMAC tag if available.\r
- *\r
- * @return the OMAC tag.\r
- */\r
- void final(byte *tag);\r
-\r
- /**\r
- * Get the default tag size for the underlying block cipher.\r
- *\r
- * @return the default tag size in bytes.\r
- */\r
- uint tagSize() {\r
- return block_size;\r
- }\r
-\r
-private:\r
- BlockCipher *_E; // block cipher context\r
- uint block_size;\r
- uint t; // remaining space on T, in bytes\r
- uint mask;\r
- uint ready;\r
- byte L[OMAC_MAXBLOCKSIZE]; // OMAC padding (block_size bytes): B = 2L, P = 4L\r
- byte T[OMAC_MAXBLOCKSIZE]; // OMAC tag (block_size bytes)\r
-};\r
-\r
-#endif /* __OMAC_H */\r
-\r
+++ /dev/null
-/**
- *@memo Implementation of the modified counter mode
- *@doc
- *@author A. MAGNIEZ (FT R&D - DTL/SSR)
- *
- * Copyright 2006 The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include "SOBMMO.h"
-#include <stdlib.h>
-#include <string.h>
-#include "eap_psk.h"
-
-/**
- *@memo default constructor
- */
-SOBMMO::SOBMMO():sizeBlock(0),nbOutputBlocks(0),outputBlocks(NULL) {
-}
-
-/**
- *@memo default destructor
- */
-SOBMMO::~SOBMMO() {
- if(outputBlocks!=NULL) {
- free(outputBlocks);
- }
-}
-
-/**
- *@memo this function initializes the modified counter mode
- *@param K, the dedicated key (its size must be equal to the block size of E)
- *@param E, the block cipher context
- *@param inputBlock, the input block (its size must be equal to the block size of E)
- *@param nb, the number of wanted output blocks
- *@param counterValues, the counter values (its size must be nbOutputBlock*sizeBlock)
- *@return 1 if the output blocks have been produced, 0 in the other cases.
- */
-int SOBMMO::initialize(const byte* K, BlockCipher* E,const byte* inputBlock,int nb,const byte* counterValues){
- int i; // iterator
- char hexstr[1024];
- byte buf[16];
-
- sizeBlock=E->blockSize();
- nbOutputBlocks=nb;
-
-
- // allocate memory for the output blocks
- outputBlocks=(byte *)malloc(sizeBlock*nbOutputBlocks);
- if(outputBlocks==NULL){
- return 0;
- }
-
- // debug traces
- pskConvertHex((char *)K, (char *)&hexstr, sizeBlock);
- DEBUG2("SOBMMO::initialize: K=");
- DEBUG2((char *)&hexstr);
-
- pskConvertHex((char *)inputBlock, (char *)&hexstr, sizeBlock);
- DEBUG2("SOBMMO::initialize: inputBlock=");
- DEBUG2((char *)&hexstr);
-
- pskConvertHex((char *)counterValues, (char *)&hexstr, sizeBlock*nbOutputBlocks);
- DEBUG2("SOBMMO::initialize: counterValues=");
- DEBUG2((char *)&hexstr);
-
- E->makeKey(K,sizeBlock,DIR_ENCRYPT);
- E->encrypt(inputBlock,outputBlocks);
-
- // duplicate the first result
- for(i=1;i<nbOutputBlocks;i++)
- {
- memcpy(outputBlocks+i*sizeBlock,outputBlocks,sizeBlock);
- }
-
- pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
- DEBUG2("SOBMMO::initialize: outputBlocks before XOR=");
- DEBUG2((char *)&hexstr);
-
- // XOR counter values
- for(i=0;i<(nbOutputBlocks*sizeBlock);i++)
- {
- *(outputBlocks+i)=(*(outputBlocks+i))^(*(counterValues+i));
- }
-
- pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
- DEBUG2("SOBMMO::initialize: outputBlocks after XOR=");
- DEBUG2((char *)&hexstr);
-
- // in order to check that AES(K,M) is valid
- E->encrypt(outputBlocks,buf);
- pskConvertHex((char *)buf, (char *)&hexstr, 16);
- DEBUG2("SOBMMO::initialize: buf=");
- DEBUG2((char *)&hexstr);
-
- // produce each output block
- for(i=0;i<nbOutputBlocks;i++)
- {
- E->encrypt(outputBlocks+i*sizeBlock,outputBlocks+i*sizeBlock); // Be careful, pt=ct !!! TBTested
- }
-
- pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
- DEBUG2("SOBMMO::initialize: produced output blocks=");
- DEBUG2((char *)&hexstr);
-
- return 1;
-
-}
-
-
-/**
- *@memo this function returns an output block
- *@param id, the number of the wanted output block (the numerotation begins at 1 !!)
- */
-byte* SOBMMO::getOutputBlock(int id){
- byte* output=NULL;
-
- if(id<1 || id>nbOutputBlocks) {
- return NULL;
- }
-
- output=(byte*)malloc(sizeBlock);
- if(output==NULL){
- return NULL;
- }
- memcpy(output,outputBlocks+(id-1)*sizeBlock,sizeBlock);
- return output;
-}
+++ /dev/null
-/**\r
- *@memo Implementation of the modified counter mode\r
- *@doc \r
- *@author A. MAGNIEZ (FT R&D - DTL/SSR) \r
- *\r
- * Copyright 2006 The FreeRADIUS server project\r
- */\r
-\r
-#ifndef _SOBMMO_H_\r
-#define _SOBMMO_H_\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(SOBMMO_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-\r
-class SOBMMO {\r
- public:\r
- \r
- SOBMMO();\r
- \r
- int initialize(const byte* K, BlockCipher* E,const byte* inputBlock,int nb,const byte* counterValues);\r
- \r
- byte* getOutputBlock(int id);\r
- \r
- virtual ~SOBMMO();\r
- \r
-private:\r
- int sizeBlock; //the size of a block cipher (input and output) in bytes\r
- int nbOutputBlocks; //number of required output blocks\r
- byte* outputBlocks; //pointer to output blocks\r
-};\r
-\r
-#endif\r
+++ /dev/null
-/* $Id$ */
-
-/*
- * eap_psk.cpp
- *
- * Implementation of the EAP-PSK packet management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "eap_psk.h"
-
-
-/*
- *
- * PSK Packet Format in EAP
- * --- ------ ------ -- ---
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Code | Identifier | Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Type | Data
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- */
-
-
-int pskConvertHex(char *inbytes, char *outstr, int numbytes)
-{
- int i;
- char buildstr[1024], tempstr[10];
-
- memset(buildstr, 0, 1024);
-
- for (i=0;i<numbytes;i++)
- {
- sprintf((char *)tempstr, "%02X",(unsigned char)inbytes[i]);
- strcat((char *)buildstr, (char *)tempstr);
- }
- strcpy(outstr, (char *)buildstr);
-
- return 1;
-}
-
-
-int pskHex2Bin(const char *hex, unsigned char *bin, int numbytes) {
- int len = strlen(hex);
- char c;
- int i;
- unsigned char v;
- for (i = 0; i < numbytes; i++) {
- c = hex[2*i];
- if (c >= '0' && c <= '9') {
- v = c - '0';
- } else if (c >= 'A' && c <= 'F') {
- v = c - 'A' + 10;
- } else if (c >= 'a' && c <= 'f') {
- v = c - 'a' + 10;
- } else {
- //v = 0;
- return 0; // non hexa character
- }
- v <<= 4;
- c = hex[2*i + 1];
- if (c >= '0' && c <= '9') {
- v += c - '0';
- } else if (c >= 'A' && c <= 'F') {
- v += c - 'A' + 10;
- } else if (c >= 'a' && c <= 'f') {
- v += c - 'a' + 10;
- } else {
- //v = 0;
- return 0; // non hexa character
- }
- bin[i] = v;
- }
- return 1;
-}
-
-
-int pskGetRandomBytes(void *buf, int nbytes){
- FILE *fptr=NULL;
- int written=0;
-
- if((fptr = fopen("/dev/urandom","r")) == NULL) {
- radlog(L_ERR,"pskGetRandomBytes: urandom device not accessible");
- return 0;
- }
-
- if((written = fread(buf,1,nbytes,fptr)) != nbytes) {
- radlog(L_ERR,"pskGetRandomBytes: number not generated");
- return 0;
- }
-
- fclose(fptr);
-
- return 1;
-}
+++ /dev/null
-/* $Id$ */
-
-/*
- * eap_psk.h
- *
- * Implementation of the EAP-PSK packet management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-
-
-#ifndef _EAP_PSK_H
-#define _EAP_PSK_H
-
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_psk_h, "$Id$")
-
-#include "eap.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-// EAP-PSK Type
-#define EAPPSK_TYPE 255
-
-// EXT_Payload maximum length in bytes
-#define EXT_PAYLOAD_MAX_LEN 977
-
-#define PSK_PCHANNEL_REPLAY_COUNTER_SIZE sizeof(unsigned long int) // size in octets
-#define PSK_KEY_SIZE (PSK_AK_SIZE+PSK_KDK_SIZE) // size in octets
-#define PSK_AK_SIZE 16 // size in octets
-#define PSK_KDK_SIZE 16 // size in octets
-#define PSK_TEK_SIZE 16 // size in octets
-#define PSK_MSK_SIZE 64 // size in octets
-#define PSK_EMSK_SIZE 64 // size in octets
-#define PSK_RANDOM_NUMBER_SIZE 16 // size in octets
-#define PSK_MAC_SIZE 16 // size in octets
-#define EAP_HEADER_SIZE 5 // size in octets
-#define PSK_SIZE 16
-
-
-
-// EAP-PSK attribute flags
-#define PSK_STATUS_CONT 0x40
-#define PSK_STATUS_DONE_FAILURE 0xC0
-#define PSK_STATUS_DONE_SUCCESS 0x80
-
-#define PSK_IS_EXT 0x20
-
-
-// the EAP-PSK configuration parameters
-typedef struct eap_psk_conf {
- unsigned char *privateKey; // the server private key
- unsigned char *id_s; // the server name
- unsigned int ldapSupport; // if an LDAP directory is used
- unsigned char *peerNaiAttribute; // the LDAP attribute name which corresponds to the peer NAI
- unsigned char *peerKeyAttribute; // the LDAP attribute name which corresponds to the peer Key = AK || KDK
- unsigned char *usersFilePath; // the EAP-PSK users file path
- unsigned int nbRetry; // the number of bad authorized responses while the EAP-PSK authentication
- unsigned int maxDelay; // the maximum interval in seconds between two correct responses
-} PSK_CONF;
-
-
-// data format of the first EAP-PSK message
-typedef struct psk_message_1 {
- unsigned char rand_s[PSK_RANDOM_NUMBER_SIZE];
-}psk_message_1;
-
-// data format of the second EAP-PSK message
-typedef struct psk_message_2 {
- unsigned char rand_p[PSK_RANDOM_NUMBER_SIZE];
- unsigned char mac_p[16];
- unsigned char *id_p;
-}psk_message_2;
-
-// data format of the third EAP-PSK message
-typedef struct psk_message_3 {
- unsigned char mac_s[16];
- unsigned long int nonce;
- unsigned char tag[16];
- unsigned char flags;
- unsigned char ext_type;
- unsigned char *extPayload;
-}psk_message_3;
-
-// data format of the fourth EAP-PSK message
-typedef struct psk_message_4 {
- unsigned long int nonce;
- unsigned char tag[16];
- unsigned char flags;
- unsigned char ext_type;
- unsigned char *ext_payload;
-}psk_message_4;
-
-
-/**
- *@memo this function converts a string into hexa
- *@param inbytes, pointer to a string
- *@param outstr, pointer to the hexa conversion
- *@param numbytes, number of bytes to convert
- *@return 0 if an error has occured
- */
-int pskConvertHex(char *inbytes, char *outstr, int numbytes);
-
-
-/**
- *@memo this function converts a string which contains hexa characters into hexa
- *@param inbytes, the string to convert
- *@param outstr, the conversion in hexa
- *@param numbytes, the number of bytes to convert
- *@return 0 if an error has occured
- */
-int pskHex2Bin(const char *hex, unsigned char *bin, int numbytes);
-
-
-/**
- *@memo this function delivers random bytes
- *@param buf, pointer to the buffer to fill
- *@param nbytes, number of bytes to generate
- *@return 0 if an error has occured
- */
-int pskGetRandomBytes(void *buf, int nbytes);
-
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /*_EAP_PSK_H*/
+++ /dev/null
-/* $Id$ */
-
-/*
- * eap_psk_ssm.cpp
- *
- * Implementation of the Server State Machine (SSM)
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-
-#include "autoconf.h"
-#include "libradius.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "radiusd.h"
-#include "modpriv.h"
-#include "modules.h"
-#include "modcall.h"
-#include "conffile.h"
-#include "ltdl.h"
-
-
-#include "eap_psk_ssm.h"
-#include "AES.h"
-#include "OMAC.h"
-#include "EAX.h"
-#include "SOBMMO.h"
-
-#include "userinfo.h"
-
-
-/* PSK Packet Format in EAP
- * --- ------ ------ -- ---
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Code | Identifier | Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Type | Data
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-
- */
-
-
-int pskProcess(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket){
-
- // error cases
- if(conf==NULL || session==NULL)
- {
- radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without EAP-PSK configuration and session information");
- return 0;
- }
-
- if(recvPacket && (recvPacket->code!=PW_EAP_RESPONSE || recvPacket->type.type!=EAPPSK_TYPE))
- {
- radlog(L_ERR,"pskProcess: EAP-PSK Response expected");
- return 0;
- }
-
- switch(session->state)
- {
- case INIT: return pskInit(conf,session,sentPacket);
- case RANDSENT:
- if(recvPacket) return pskRandSent(conf,session, recvPacket,sentPacket);
- case PCHANNEL:
- if(recvPacket) return pskPChannel(conf,session,recvPacket,sentPacket);
- default:
- radlog(L_ERR,"pskProcess: Impossible to process the EAP-PSK authentication");
- return 0;
- }
-
-}
-
-
-int pskInit(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *sentPacket){
-
- char hexstr[1024];
-
- session->nbRetry=0;
- session->pChannelReplayCounter=0;
- session->authStatus=PSK_STATUS_CONT;
- session->isSupportedExt=1;
- session->extType=0;
-
- sentPacket->code=PW_EAP_REQUEST;
- sentPacket->length=PSK_RANDOM_NUMBER_SIZE+EAP_HEADER_SIZE;
- sentPacket->type.type=EAPPSK_TYPE;
- sentPacket->type.length=PSK_RANDOM_NUMBER_SIZE;
- sentPacket->type.data=NULL;
- sentPacket->type.data=(unsigned char*)malloc(PSK_RANDOM_NUMBER_SIZE);
-
- if(sentPacket->type.data==NULL)
- {
- radlog(L_ERR,"pskInit: Out of memory");
- return 0;
- }
-
- // generate a 128-bit random value and put this value in session->rand_s
- if(!pskGetRandomBytes(sentPacket->type.data,PSK_RANDOM_NUMBER_SIZE)) {
- radlog(L_ERR,"pskInit: problem during random number generation");
- return 0;
- }
-
- pskConvertHex((char *)sentPacket->type.data, (char *)hexstr,PSK_RANDOM_NUMBER_SIZE);
- DEBUG2("pskInit: random number RA :");
- DEBUG2((char *)hexstr);
-
- // save this value in session information
- memcpy(session->rand_s,sentPacket->type.data,PSK_RANDOM_NUMBER_SIZE);
-
- session->state=RANDSENT;
-
- return 1;
-
-}
-
-
-int pskRandSent(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket){
-
- /* the received packet is shown below
- *
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Code=2 | Identifier | Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Type EAP-PSK | |
- * +-+-+-+-+-+-+-+-+ +
- * | |
- * + +
- * | RAND_P |
- * + +
- * | |
- * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | |
- * +-+-+-+-+-+-+-+-+ +
- * | |
- * + +
- * | MAC_P |
- * + +
- * | |
- * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | |
- * +-+-+-+-+-+-+-+-+ :
- * : ID_P :
- * : :
- * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-
- psk_message_2 *psk_msg_2;
- psk_message_3 *psk_msg_3;
- int identitySize;
- char hexstr[1024];
-
- unsigned char buffer[PSK_MAC_SIZE];
- unsigned char *data;
- unsigned char *ptr;
- unsigned char buftmp[PSK_AK_SIZE+PSK_KDK_SIZE];
-
- //user profile
- userinfo_t* uinfo = NULL;
-
- char **psk_vals;
- char *psk_val;
- int i=0;
- char **atts;
- unsigned char privateKey[PSK_SIZE];
-
- // for the mac calculation
- OMAC om;
- AES c;
-
- // for the key derivation
- SOBMMO sob;
- unsigned char *block;
- // counter values
- unsigned char counterValues[]={
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09};
-
-
- // for the pchannel
- unsigned char nn[PSK_RANDOM_NUMBER_SIZE];
- unsigned char eapHeader[EAP_HEADER_SIZE];
- EAX eax;
-
-
-
- if(recvPacket->length<(EAP_HEADER_SIZE+PSK_RANDOM_NUMBER_SIZE+PSK_MAC_SIZE+1))
- {
- // the packet is malformed
- DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
- // retrieve the identity of the peer, ID_P
- identitySize=recvPacket->length-(EAP_HEADER_SIZE+PSK_RANDOM_NUMBER_SIZE+PSK_MAC_SIZE);
- session->id_p=(unsigned char *)malloc(identitySize+1);
- if(session->id_p==NULL)
- {
- radlog(L_ERR,"pskRandSent: Out of memory");
- return 0;
- }
- psk_msg_2=(psk_message_2*)recvPacket->type.data;
- memcpy(session->id_p,&(psk_msg_2->id_p),identitySize);
- session->id_p[identitySize]='\0';
-
- // search the peer identity in the user file whose path is conf->usersFilePath
-
- uinfo = pskGetUserInfo((char*)conf->usersFilePath, (char*)session->id_p);
- if (uinfo)
- {
-
- DEBUG2("pskRandSent: identity successfully checked");
- DEBUG2("pskRandSent: saving peer information");
-
- // save keys
- memcpy(session->ak,uinfo->AK,PSK_AK_SIZE);
- memcpy(session->kdk,uinfo->KDK,PSK_KDK_SIZE);
-
- DEBUG2("pskRandSent: found user %s in %s",session->id_p, conf->usersFilePath);
-
- free(uinfo);
-
- } else {
-
- // the peer identity wasn't found
- DEBUG2("pskRandSent: the peer identity isn't valid");
- DEBUG2("pskRandSent: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
- // calculate the following MAC: MAC(session->ak, ID_P || conf->id_s || session->rand_s || RAND_P)
-
- // making the formula
- data=(unsigned char *)malloc(strlen((char*)session->id_p)+strlen((char*)conf->id_s)+2*PSK_RANDOM_NUMBER_SIZE);
- if(data==NULL) {
- radlog(L_ERR,"pskRandSent: out of memory");
- return 0;
- }
- ptr=data;
- memcpy(ptr,session->id_p,strlen((char*)session->id_p));
- ptr+=strlen((char*)session->id_p);
- memcpy(ptr,conf->id_s,strlen((char*)conf->id_s));
- ptr+=strlen((char*)conf->id_s);
- memcpy(ptr,session->rand_s,PSK_RANDOM_NUMBER_SIZE);
- ptr+=PSK_RANDOM_NUMBER_SIZE;
- memcpy(ptr,psk_msg_2->rand_p,PSK_RANDOM_NUMBER_SIZE);
-
- pskConvertHex((char *)data, (char *)hexstr,strlen((char*)session->id_p)+strlen((char*)conf->id_s)+2*PSK_RANDOM_NUMBER_SIZE);
- DEBUG2("pskRandSent: [B||A||RA||RB] :");
- DEBUG2((char *)hexstr);
-
- pskConvertHex((char *)(session->ak), (char *)hexstr,PSK_AK_SIZE);
- DEBUG2("pskRandSent: AK :");
- DEBUG2((char *)hexstr);
-
-
- // obtain the mac
-
- c.makeKey(session->ak,PSK_AK_SIZE,DIR_ENCRYPT);
- om.init(&c);
- om.update(data,strlen((char*)session->id_p)+strlen((char*)conf->id_s)+2*PSK_RANDOM_NUMBER_SIZE);
- om.final(buffer);
- free(data);
-
- pskConvertHex((char *)buffer, (char *)hexstr,PSK_MAC_SIZE);
- DEBUG2("pskRandSent: MAC of [B||A||RA||RB] :");
- DEBUG2((char *)hexstr);
-
-
- if(memcmp(buffer,psk_msg_2->mac_p,PSK_MAC_SIZE))
- {
- // the received MAC attribute is not correct
- DEBUG2("pskRandSent: the received MAC attribute isn't correct");
- DEBUG2("pskRandSent: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
-
- DEBUG2("pskRandSent: the received MAC attribute is correct");
-
- // KEY DERIVATION
-
- // initialize the sobmmo
- sob.initialize(session->kdk,&c,psk_msg_2->rand_p,9,counterValues);
-
- // get the TEK
- block=sob.getOutputBlock(1);
- memcpy(session->tek,block,PSK_TEK_SIZE);
- free(block);
-
- pskConvertHex((char *)session->tek, (char *)hexstr, PSK_TEK_SIZE);
- DEBUG2("pskRandSent: TEK :");
- DEBUG2((char *)hexstr);
-
- // get the MSK
- for(int i=0;i<4;i++)
- {
- block=sob.getOutputBlock(i+2);
- memcpy(&session->msk[i*16],block,16);
- free(block);
- }
-
- pskConvertHex((char *)session->msk, (char *)hexstr, PSK_MSK_SIZE);
- DEBUG2("pskRandSent: MSK :");
- DEBUG2((char *)hexstr);
-
- // get the EMSK
- for(int i=0;i<4;i++)
- {
- block=sob.getOutputBlock(i+6);
- memcpy(&session->emsk[i*16],block,16);
- free(block);
- }
-
- pskConvertHex((char *)session->emsk, (char *)hexstr, PSK_EMSK_SIZE);
- DEBUG2("pskRandSent: EMSK :");
- DEBUG2((char *)hexstr);
-
-
- // obtain the mac of [A||RB]
- data=(unsigned char *)malloc(strlen((char*)conf->id_s)+PSK_RANDOM_NUMBER_SIZE);
- if(data==NULL) {
- radlog(L_ERR,"pskRandSent: out of memory");
- return 0;
- }
- memcpy(data,conf->id_s,strlen((char*)conf->id_s));
- memcpy(data+strlen((char*)conf->id_s),psk_msg_2->rand_p,PSK_RANDOM_NUMBER_SIZE);
-
- pskConvertHex((char *)data, (char *)hexstr,strlen((char*)conf->id_s)+PSK_RANDOM_NUMBER_SIZE);
- DEBUG2("pskRandSent: [A||RB] :");
- DEBUG2((char *)hexstr);
-
- c.makeKey(session->ak,PSK_AK_SIZE,DIR_ENCRYPT);
- om.init(&c);
- om.update(data,strlen((char*)conf->id_s)+PSK_RANDOM_NUMBER_SIZE);
- om.final(buffer);
- free(data);
-
- pskConvertHex((char *)&buffer, (char *)hexstr,16);
- DEBUG2("pskRandSent: MAC of [A||RB] :");
- DEBUG2((char *)hexstr);
-
-
- if(session->extType==0)
- {
- // standard authentication
-
- sentPacket->code=PW_EAP_REQUEST;
- sentPacket->length=EAP_HEADER_SIZE+2*PSK_MAC_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+1;
- sentPacket->type.type=EAPPSK_TYPE;
- sentPacket->type.length=2*PSK_MAC_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+1;
- sentPacket->type.data=NULL;
- sentPacket->type.data=(unsigned char*)malloc(2*PSK_MAC_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+1);
-
- if(sentPacket->type.data==NULL)
- {
- radlog(L_ERR,"pskRandSent: Out of memory");
- return 0;
- }
-
- psk_msg_3=(psk_message_3*)sentPacket->type.data;
-
- // add to sentPacket the following MAC: MAC(session->AK, conf->id_s || RAND_P)
- memcpy(psk_msg_3->mac_s,buffer,PSK_MAC_SIZE);
-
- // add to sentPacket the following information:
- // R = DONE_SUCCESS (the R flag is equal to session->authStatus)
- // E=0
- psk_msg_3->nonce=htonl(session->pChannelReplayCounter);
-
- // calculate the EAP header
- eapHeader[0]=sentPacket->code;
- eapHeader[1]=(recvPacket->id)+1; // we suppose that the identifier is incremented by 1
-
- sentPacket->length=htons(sentPacket->length);
- memcpy(&(eapHeader[2]),&(sentPacket->length),2);
- sentPacket->length=ntohs(sentPacket->length);
-
- eapHeader[4]=sentPacket->type.type;
-
- pskConvertHex((char *)eapHeader, (char *)hexstr,EAP_HEADER_SIZE);
- DEBUG2("pskRandSent: eapHeader :");
- DEBUG2((char *)hexstr);
-
- // the replay counter is the least significant bytes of the nonce !
- memset(nn,0,PSK_RANDOM_NUMBER_SIZE);
- memcpy(&nn[PSK_RANDOM_NUMBER_SIZE-PSK_PCHANNEL_REPLAY_COUNTER_SIZE],&(psk_msg_3->nonce),PSK_PCHANNEL_REPLAY_COUNTER_SIZE);
-
- pskConvertHex((char *)nn, (char *)hexstr,PSK_RANDOM_NUMBER_SIZE);
- DEBUG2("pskRandSent: nn :");
- DEBUG2((char *)hexstr);
-
- session->authStatus=PSK_STATUS_DONE_SUCCESS;
-
- // EAX encryption
-
- eax.initialize(session->tek, PSK_TEK_SIZE, AES_BLOCKSIZE, &c);
-
- eax.provideNonce((byte*)nn,PSK_RANDOM_NUMBER_SIZE);
- eax.provideHeader((byte*)eapHeader,EAP_HEADER_SIZE);
- eax.computeCiphertext((byte*)&(session->authStatus),sizeof(session->authStatus),(byte*)&(psk_msg_3->flags));
- eax.computeTag((byte*)psk_msg_3->tag);
-
- // !!! BE CAREFUL !!!
- // the authorization isn't taken into account in this implementation
- // that's why R=DONE_SUCCESS
-
- } else {
- // extended authentication
-
-
- // !!!!! NOT IMPLEMENTED !!!!!!
- return 0;
-
- /*
-
- // call the extension which must update the session->authStatus, i.e. the result of the EAP-PSK authentication
- // see the pskExtension function declaration for more details
- void *payloadOut=NULL;
- int sizePayloadOut=0;
- int resul;
- resul=pskExtension(conf,session,PSK_STATUS_CONT,NULL,0,&payloadOut,&sizePayloadOut);
-
- if(!resul || (sizePayloadOut<1) || (sizePayloadOut>EXT_PAYLOAD_MAX_LEN))
- {
- //the extension has failed
- // the authentication must fail
- // the sentPacket must be a EAP_Failure packet
- return 1;
- }
-
- // add to sentPacket the following information:
- // R = CONT or DONE_FAILURE or DONE_SUCCESS thanks to session->authStatus
- // E = 1
- // EXT_Type=session->extType
- // EXT_payload=payloadOut
-
- */
-
- }
-
- session->pChannelReplayCounter++;
-
- session->state=PCHANNEL;
-
-
- return 1;
-
-}
-
-
-
-int pskPChannel(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket){
-
- /* the received packet is shown below
- *
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Code=2 | Identifier | Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Type EAP-PSK | Nonce... :
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ...Nonce | |
- * +-+-+-+-+-+-+-+-+ +
- * | |
- * + +
- * | TAG |
- * + +
- * | |
- * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | R |E| Reserved|EXT_Type (opt)| |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++ +
- * : :
- * : EXT_Payload (optional) :
- * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * EXT_Type and EXT_Payload must be in the EAP packet when E is set to 1
- * EXT_Payload could be null
- *
- */
-
- psk_message_4 *psk_msg_4;
-
- // for the pchannel
- unsigned char eapHeader[EAP_HEADER_SIZE];
- unsigned char nn[PSK_RANDOM_NUMBER_SIZE];
- EAX eax;
- AES c;
- bool st;
- unsigned char flags;
-
- if(recvPacket->length<(EAP_HEADER_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+PSK_MAC_SIZE+1))
- {
- // the packet is malformed
- // the session->nbRetry isn't incremented
- // sentPacket must be the previous request sent by the server ###### PB TIMER ########
-
- DEBUG2("pskPChannel: receiving a invalid EAP-PSK packet: the packet is malformed");
- DEBUG2("pskPChannel: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
-
- psk_msg_4=(psk_message_4*)recvPacket->type.data;
-
-
- if(ntohl(psk_msg_4->nonce)!=session->pChannelReplayCounter)
- {
- // the received packet isn't awaited
- // the session->nbRetry isn't incremented
- // sentPacket must be the previous request sent by the server
-
- DEBUG2("pskPChannel: receiving a invalid EAP-PSK packet: the replay counter isn't valid");
- DEBUG2("pskPChannel: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
- // decrypt the received packet with the EAX mode and check the EAP header
-
- // calculate the EAP header
- eapHeader[0]=recvPacket->code;
- eapHeader[1]=recvPacket->id;
-
- recvPacket->length=htons(recvPacket->length);
- memcpy(&(eapHeader[2]),&(recvPacket->length),2);
- recvPacket->length=ntohs(recvPacket->length);
-
- eapHeader[4]=recvPacket->type.type;
-
- // the replay counter is the least significant bytes of the nonce !
- memset(nn,0,PSK_RANDOM_NUMBER_SIZE);
- memcpy(&nn[PSK_RANDOM_NUMBER_SIZE-PSK_PCHANNEL_REPLAY_COUNTER_SIZE],&(psk_msg_4->nonce),PSK_PCHANNEL_REPLAY_COUNTER_SIZE);
-
- // EAX encryption
-
- eax.initialize(session->tek, PSK_TEK_SIZE, AES_BLOCKSIZE, &c);
-
- eax.provideNonce((byte*)nn,PSK_RANDOM_NUMBER_SIZE);
- eax.provideHeader((byte*)eapHeader,EAP_HEADER_SIZE);
- eax.provideCiphertext((byte*)&(psk_msg_4->flags),sizeof(psk_msg_4->flags));
- st=eax.checkTag((byte*)psk_msg_4->tag);
-
- if(!st){
- // the decryption ends by a failure
-
- DEBUG2("pskPChannel: receiving a invalid EAP-PSK packet: the decryption fails");
- DEBUG2("pskPChannel: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
-
- eax.computePlaintext((byte*)&(psk_msg_4->flags),sizeof(psk_msg_4->flags),(byte*)&flags);
-
- if((((flags & PSK_IS_EXT)==PSK_IS_EXT) && recvPacket->length<(EAP_HEADER_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+PSK_MAC_SIZE+2)) || (((flags & PSK_IS_EXT)==0) && recvPacket->length!=(EAP_HEADER_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+PSK_MAC_SIZE+1)))
- {
- // the packet is malformed
- // the authentication must fail
- // the sentPacket must be a EAP_Failure packet
-
- DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
-
- if(session->extType==0 && ((flags & PSK_IS_EXT)==PSK_IS_EXT))
- {
- // error: standard authentication awaited
- // the authentication must fail
- // the sentPacket must be a EAP_Failure packet
-
- DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
- if(session->extType!=0 && ((flags & PSK_IS_EXT)==0))
- {
- // error: extended authentication awaited
- // the authentication must fail
- // the sentPacket must be a EAP_Failure packet
-
- DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
- sentPacket->code=PW_EAP_FAILURE;
-
- return 1;
- }
-
- if((flags & PSK_IS_EXT)==0)
- {
- // standard authentication
-
- if(((flags & PSK_STATUS_DONE_SUCCESS)==PSK_STATUS_DONE_SUCCESS) && session->authStatus==PSK_STATUS_DONE_SUCCESS)
- {
- // sentPacket must be an EAP_Success packet
- // indicate to the lower layer that the MSK and the EMSK are ready
- // the EAP-PSK authentication will end after sending sentPacket
-
- sentPacket->code=PW_EAP_SUCCESS;
-
- } else {
- // sentPacket must be an EAP_Failure packet
- // the EAP-PSK authentication will end after sending sentPacket
-
- sentPacket->code=PW_EAP_FAILURE;
-
- }
-
- } else {
- // extended authentication
-
-
- // !!!!! NOT IMPLEMENTED !!!!!
- return 0;
-
-
- /*
- if(session->isSupportedExt)
- {
-
- if(recvPacket->data.EXT_Payload)
- {
-
- // call the extension which must update the session->authStatus, i.e. the result of the EAP-PSK authentication
- // see the pskExtension function declaration for more details
- void *payloadOut=NULL;
- int sizePayloadOut=0;
- int sizePayloadIn=recvPacket->length-27; // (27=5+16+4+1+1)
- int resul;
- resul=pskExtension(conf,session,recvPacket->data.R,recvPacket->data.EXT_Payload,sizePayloadIn,&payloadOut,&sizePayloadOut);
-
- if(!resul || (sizePayloadOut<1) || (sizePayloadOut>EXT_PAYLOAD_MAX_LEN))
- {
- //the extension has failed
- // the authentication must fail
- // the sentPacket must be a EAP_Failure packet
- return 1;
- }
-
- if(recvPacket->data.R != CONT) {
- // sentPacket must be an EAP_Success packet or an EAP_Failure packet thanks to the server policy and the received R flag
- // indicate to the lower layer that the MSK and the EMSK are ready in case an EAP_Success packet must be sent
- // the EAP-PSK authentication will end after sending sentPacket
- return 1;
- }
-
- // add to sentPacket the following information:
- // R = CONT or DONE_FAILURE or DONE_SUCCESS thanks to session->authStatus
- // E = 1
- // EXT_Type=session->extType
- // EXT_payload=payloadOut
-
- } else {
- // the peer doesn't support the specified extension
-
- session->isSupportedExt=0;
-
- if(recvPacket->data.R != CONT) {
- // sentPacket must be an EAP_Success packet or an EAP_Failure packet thanks to the server policy and the received R flag
- // indicate to the lower layer that the MSK and the EMSK are ready in case of an EAP_Success packet must be sent
- // the EAP-PSK authentication will end after sending sentPacket
- return 1;
- }
-
- // add to sentPacket the following information:
- // R = DONE_FAILURE or DONE_SUCCESS thanks to the server policy
- // E = 1
- // EXT_Type=session->extType
- }
-
- } else {
-
- if(recvPacket->data.R != CONT && recvPacket->data.EXT_Payload==NULL) {
- // sentPacket must be an EAP_Success packet or an EAP_Failure packet thanks to the server policy and the received R flag
- // indicate to the lower layer that the MSK and the EMSK are ready in case of an EAP_Success packet must be sent
- // the EAP-PSK authentication will end after sending sentPacket
- return 1;
-
- } else {
- // the packet is malformed
- // the authentication must fail
- // the sentPacket must be a EAP_Failure packet
- return 1;
- }
-
- }
- */
-
- session->pChannelReplayCounter++;
- // use the EAX mode to encrypt the EXT_Payload and protect the EAP header
-
- // !!!! NOT IMPLEMENTED !!!!
- // only standard authentication supported
-
- session->pChannelReplayCounter++;
-
- }
-
- // stay in this state
- return 1;
-
-}
-
-
-
-int pskExtension(PSK_CONF *conf, PSK_SESSION *session, unsigned short receivedStatus, void *dataIn, int sizeDataIn, void **dataOut, int *sizeDataOut){
-
- // this functionality makes it possible to do authorization, account refilling...
-
- // this function must update the session->authStatus variable thanks to its policy, the received R flag, i.e. the receivedStatus variable, and the received data
-
- // !!! Be careful !!!
- // dataOut mustn't be NULL
-
- // !!!! NOT IMPLEMENTED !!!!
- return 0;
-
-}
-
-
-
-/**
- *@memo this function frees the session data
- *@param opaque, pointer to a structure which contains information session
- */
-void pskFreeSession(void *opaque){
- PSK_SESSION *session;
-
- DEBUG2("pskFreeSession:");
-
- if(!opaque) return;
-
- session=(PSK_SESSION *)opaque;
- if(!session) return;
-
- if(session->id_p) {
- free(session->id_p);
- }
-
- free(session);
-
- opaque=NULL;
-
- DEBUG2("pskFreeSession: finished");
-
-}
+++ /dev/null
-/* $Id$ */
-
-/*
- * eap_psk_ssm.h
- *
- * Implementation of the Server State Machine (SSM)
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#ifndef _EAP_PSK_SSM_H
-#define _EAP_PSK_SSM_H
-
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_psk_ssm_h, "$Id$")
-
-#include "eap_psk.h"
-#include "eap.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-
-// server states
-typedef enum {
- INIT, // the server state machine starts in the INIT state
- RANDSENT,
- PCHANNEL
-}PSK_STATE;
-
-
-// information which must be kept during the EAP-PSK session
-typedef struct psk_session_t {
- PSK_STATE state; // state of the server state machine
- unsigned char rand_s[PSK_RANDOM_NUMBER_SIZE]; // random number generated by the server
- unsigned char *id_p; // peer identity
- unsigned char ak[PSK_AK_SIZE]; // authentication key
- unsigned char kdk[PSK_KDK_SIZE]; // derivation key
- unsigned char tek[PSK_TEK_SIZE]; // TEK key
- unsigned char msk[PSK_MSK_SIZE]; // MSK key
- unsigned char emsk[PSK_EMSK_SIZE]; // EMSK key
- unsigned int nbRetry; // the current number of request re emissions
- unsigned long int pChannelReplayCounter; // the p-channel replay counter
- unsigned char extType; // the extension type if evolved authentication is used, else 0
- unsigned char authStatus; // the latest R flag sent by the server
- unsigned char isSupportedExt; // 0 if the peer doesn't support the specified extension
-}PSK_SESSION;
-
-
-/**
- *@memo this function is the entry point of the server state machine
- *@param conf, pointer to the current configuration of EAP-PSK
- *@param session, pointer to a structure which contains information session
- *@param recvPacket, pointer to a received EAP_PACKET
- *@param sentPacket, pointer to the EAP_PACKET to send
- *@return 0 if an error has occured
- */
- int pskProcess(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo this function corresponds to the first state of the server state machine
- *@param conf, pointer to the current configuration of EAP-PSK
- *@param session, pointer to a structure which contains information session
- *@param sentPacket, pointer to the EAP_PACKET to send
- *@return 0 if an error has occured
- */
- int pskInit(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo this function corresponds to the second state of the server state machine
- *@param conf, pointer to the current configuration of EAP-PSK
- *@param session, pointer to a structure which contains information session
- *@param recvPacket, pointer to a received EAP_PACKET
- *@param sentPacket, pointer to the EAP_PACKET to send
- *@return 0 if an error has occured
- */
- int pskRandSent(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo this function corresponds to the third state of the server state machine
- *@param conf, pointer to the current configuration of EAP-PSK
- *@param session, pointer to a structure which contains information session
- *@param recvPacket, pointer to a received EAP_PACKET
- *@param sentPacket, pointer to the EAP_PACKET to send
- *@return 0 if no error has occured
- */
- int pskPChannel(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo this function contains the extension to EAP-PSK
- *@param conf, pointer to the current configuration of EAP-PSK
- *@param session, pointer to a structure which contains information session
- *@param receivedStatus, the latest R flag sent by the peer
- *@param dataIn, pointer to the received data
- *@param sizeDataIn, size of the received data
- *@param dataOut, pointer to a pointer that points data to send
- *@param sizeDataOut, pointer to the size of data to be sent (sizeDataOut must be at most equal to EXT_PAYLAOD_MAX_LEN)
- *@return 0 if an error has occured
- */
- int pskExtension(PSK_CONF *conf, PSK_SESSION *session, unsigned short receivedStatus, void *dataIn, int sizeDataIn, void **dataOut, int *sizeDataOut);
-
-
-/**
- *@memo this function frees an existing session from memory
- *@param opaque, pointer to a structure which contains information session
- */
- void pskFreeSession(void *opaque);
-
-
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /*_EAP_PSK_SSM_H*/
+++ /dev/null
-/* $Id$ */
-
-/*
- * rlm_eap_psk.cpp
- *
- * Implementation of the interface between the radius server and
- * the eap-psk protocol
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-
-
-#include "autoconf.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-
-#include "eap_psk.h"
-#include "eap_psk_ssm.h"
-
-static CONF_PARSER moduleConfig[] = {
- { "private_key", PW_TYPE_STRING_PTR,
- offsetof(PSK_CONF, privateKey), NULL, NULL },
- { "server_name", PW_TYPE_STRING_PTR,
- offsetof(PSK_CONF, id_s), NULL, "pskserver" },
- { "peer_nai_attribute", PW_TYPE_STRING_PTR,
- offsetof(PSK_CONF, peerNaiAttribute), NULL, "eapPskPeerNAI" },
- { "peer_key_attribute", PW_TYPE_STRING_PTR,
- offsetof(PSK_CONF, peerKeyAttribute), NULL, "eapPskPeerKey" },
- { "users_file_path", PW_TYPE_STRING_PTR,
- offsetof(PSK_CONF, usersFilePath), NULL, "/etc/raddb/users.psk" },
- { "nb_retry", PW_TYPE_INTEGER,
- offsetof(PSK_CONF, nbRetry), NULL, "3" },
- { "max_delay", PW_TYPE_INTEGER,
- offsetof(PSK_CONF, maxDelay), NULL, "5" },
- { NULL, -1, 0, NULL, NULL } /* end the list */
-};
-
-
-/**
- *@memo this function add value pair to reply
- */
-static void addReply(VALUE_PAIR** vp,
- const char* name, unsigned char* value, int len)
-{
- VALUE_PAIR *reply_attr;
- reply_attr = pairmake(name, "", T_OP_EQ);
- if (!reply_attr) {
- DEBUG("rlm_eap_psk: "
- "add_reply failed to create attribute %s: %s\n",
- name, librad_errstr);
- return;
- }
-
- memcpy(reply_attr->vp_octets, value, len);
- reply_attr->length = len;
- pairadd(vp, reply_attr);
-}
-
-/*
- *@memo this function detaches the module
- */
-static int pskDetach(void *arg)
-{
- PSK_CONF *inst = (PSK_CONF *) arg;
-
- if (inst->privateKey) free(inst->privateKey);
- if (inst->id_s) free(inst->id_s);
- if (inst->peerNaiAttribute) free(inst->peerNaiAttribute);
- if (inst->peerKeyAttribute) free(inst->peerKeyAttribute);
- if(inst->usersFilePath) free(inst->usersFilePath);
-
- free(inst);
-
- return 0;
-}
-
-
-/*
- *@memo this function attaches the module
- */
-static int pskAttach(CONF_SECTION *cs, void **instance)
-{
- PSK_CONF *inst;
-
- inst = (PSK_CONF*)malloc(sizeof(*inst));
- if (!inst) {
- radlog(L_ERR, "rlm_eap_psk: out of memory");
- return -1;
- }
- memset(inst, 0, sizeof(*inst));
-
- // parse the configuration attributes
- if (cf_section_parse(cs, inst, moduleConfig) < 0) {
- pskDetach(inst);
- return -1;
- }
-
- *instance = inst;
- return 0;
-}
-
-
-
-/**
- *@memo this function begins the conversation when the EAP-Identity response is received
- * send an initial eap-psk request, ie IDREQ
- *@param handler, pointer to specific information about the eap-psk protocol
- */
-static int pskInitiate(void *type_arg, EAP_HANDLER *handler)
-{
- PSK_SESSION *session;
- PSK_CONF *conf=(PSK_CONF*)type_arg;
-
- if(conf==NULL)
- {
- radlog(L_ERR,"rlm_eap_psk: Cannot initiate EAP-PSK without having its configuration");
- return 0;
- }
-
- DEBUG2("rlm_eap_psk: privateKey: %s",conf->privateKey);
- DEBUG2("rlm_eap_psk: id_s: %s", conf->id_s);
- DEBUG2("rlm_eap_psk: peerNaiAttribute: %s", conf->peerNaiAttribute);
- DEBUG2("rlm_eap_psk: peerKeyAttribute: %s", conf->peerKeyAttribute);
- DEBUG2("rlm_eap_psk: usersFilePath: %s", conf->usersFilePath);
-
- // allocate memory in order to save the state of session
- handler->opaque=malloc(sizeof(PSK_SESSION));
- if(!handler->opaque) {
- radlog(L_ERR,"rlm_eap_psk: Out of memory");
- return 0;
- }
-
- // save this pointer in the handler
- session=(PSK_SESSION *)handler->opaque;
- handler->free_opaque=pskFreeSession;
-
- // initializing session information
- memset(session,0,sizeof(PSK_SESSION));
- session->state=INIT;
-
- handler->stage=AUTHENTICATE;
-
- // initiate the eap-psk protocol
- return pskProcess(conf,session,NULL,handler->eap_ds->request);
-
-}
-
-
-
-
-/**
- *@memo this function uses specific EAP-Type authentication mechanism to authenticate the user
- * may be called many times
- *@param handler, pointer to specific information about the eap-psk protocol
- */
-static int pskAuthenticate(void *arg, EAP_HANDLER *handler)
-{
- PSK_SESSION *session;
- PSK_CONF *conf=(PSK_CONF*)arg;
- int resul;
-
- if(conf==NULL)
- {
- radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without having EAP-PSK configuration");
- return 0;
- }
-
- if(!handler->opaque) {
- radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without EAP-PSK session information");
- return 0;
- }
-
- // find the session information
- session=(PSK_SESSION *)handler->opaque;
-
- resul=pskProcess(conf,session,handler->eap_ds->response,handler->eap_ds->request);
-
- if(handler->eap_ds->request->code==PW_EAP_SUCCESS) {
- // sending keys
- addReply(&handler->request->reply->vps,"MS-MPPE-Recv-Key",session->msk,32);
- addReply(&handler->request->reply->vps,"MS-MPPE-Send-Key",&session->msk[32],32);
- }
-
- return resul;
-
-}
-
-
-EAP_TYPE rlm_eap_psk = {
- "eap_psk",
- pskAttach, // attach
- pskInitiate, // Start the initial request, after Identity
- NULL,
- pskAuthenticate, // authentication
- pskDetach // detach
-};
+++ /dev/null
-/* $Id$ */
-
-
-/*
- * userinfo.c
- *
- * Implementation of the user management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "userinfo.h"
-#include "eap_psk_ssm.h"
-#include "eap_psk.h" //hex2Bin()
-
-
-
-userinfo_t* pskGetUserInfo(char* path, char* peerID)
-{
- FILE* fp;
- char buff[1024]; //FIXME: give the buffer a proper size
- //when we know more about ID length
- userinfo_t* uinfo = NULL;
- int found = 0;
- char* AK = NULL;
- char* KDK = NULL;
- int res;
-
- fp = fopen(path, "r");
- if (fp == NULL)
- {
- radlog(L_ERR, "pskGetUserInfo: failed to open PSK users file");
- return NULL;
- }
-
- while (!found && fgets(buff, sizeof(buff), fp))
- {
- unsigned int i = 0;
-
- // ignore comments
- if (buff[0] == '#')
- continue;
-
- // read this login name
- while (! isspace(buff[i]))
- i++;
-
- // is it the one we looking for?
- if ((i != strlen(peerID))
- || (strncmp(peerID, buff, i) != 0))
- continue;
- else
- found = 1;
-
- // skip spaces
- while (isspace(buff[i]))
- i++;
-
- // prepare to store user info
- uinfo = (userinfo_t*) malloc(sizeof(userinfo_t));
- if (uinfo == NULL)
- {
- radlog(L_ERR, "pskGetUserInfo: out of memory");
- return NULL;
- }
-
- //get AK
- AK = strndup(buff + i, PSK_AK_STRLEN);
- if (AK == NULL) {
- radlog(L_ERR, "pskGetUserInfo: out of memory");
- free(uinfo);
- return NULL;
- }
- //FIXME: shouldnt we check the key size?
- /*
- else if (strlen(AK) != 32) {
- log();
- return NULL;
- }
- */
- res=pskHex2Bin(AK, &(uinfo->AK),PSK_AK_SIZE);
-
- if(!res)
- {
- radlog(L_ERR, "pskGetUserInfo: the key isn't in hexadecimal format");
- free(uinfo);
- free(AK);
- return NULL;
- }
-
- //get KDK
- KDK = strndup(buff + i + PSK_AK_STRLEN, PSK_KDK_STRLEN);
- if (KDK == NULL) {
- radlog(L_ERR, "psk_get_user_info: out of memory");
- free(uinfo);
- free(AK);
- return NULL;
- }
- //FIXME: shouldnt we check the key size?
- /*
- else if (strlen(KDK) != 32) {
- log();
- return NULL;
- }
- */
- res=pskHex2Bin(KDK, &(uinfo->KDK),PSK_KDK_SIZE);
-
- if(!res)
- {
- radlog(L_ERR, "pskGetUserInfo: the key isn't in hexadecimal format");
- free(uinfo);
- free(AK);
- free(KDK);
- return NULL;
- }
-
- free(AK);
- free(KDK);
- }
-
-
- // if user was not found, NULL is returned
- fclose(fp);
- return uinfo;
-}
-
+++ /dev/null
-/* $Id$ */
-
-
-/*
- * userinfo.h
- *
- * Implementation of the user management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#ifndef __USERINFO_H__
-#define __USERINFO_H__
-
-#include <freeradius-devel/ident.h>
-RCSIDH(userinfo_h, "$Id$")
-
-
-#include "eap_psk_ssm.h" // PSK_AK/KDK_SIZE
-
-
-
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-typedef struct s_userinfo {
- // char* name;
- unsigned char AK[PSK_AK_SIZE];
- unsigned char KDK[PSK_KDK_SIZE];
- // s_userinfo* next;
-} userinfo_t;
-
-
-
-
-#define ASCII_PER_BYTE 2
-#define PSK_AK_STRLEN (PSK_AK_SIZE*ASCII_PER_BYTE)
-#define PSK_KDK_STRLEN (PSK_KDK_SIZE*ASCII_PER_BYTE)
-
-
-
-
-userinfo_t* pskGetUserInfo(char* filename, char* peerID);
-
-//int psk_user_free(); //A VOIR
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /*__USERINFO_H__*/
+++ /dev/null
-# usernames and keys are supposed to be on the same line, separated by
-# white spaces or tabs
-# reading stops after EOF or white line
-#
-
-#user example
-aurelien 9A33DC804926D834894423BDEA4BAA59F6294F39A00D960B3A0DBB404DC62C5C
-
-
-
-
-