import from branch_1_1:
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_psk / SOBMMO.cpp
1 /**
2  *@memo         Implementation of the modified counter mode
3  *@doc
4  *@author       A. MAGNIEZ (FT R&D - DTL/SSR)
5  *
6  * Copyright 2006 The FreeRADIUS server project
7  */
8
9 #include <freeradius-devel/ident.h>
10 RCSID("$Id$")
11
12 #include "SOBMMO.h"
13 #include <stdlib.h>
14 #include <string.h>
15 #include "eap_psk.h"
16
17 /**
18  *@memo         default constructor
19  */
20 SOBMMO::SOBMMO():sizeBlock(0),nbOutputBlocks(0),outputBlocks(NULL) {
21 }
22
23 /**
24  *@memo         default destructor
25  */
26 SOBMMO::~SOBMMO() {
27   if(outputBlocks!=NULL) {
28     free(outputBlocks);
29   }
30 }
31
32 /**
33  *@memo         this function initializes the modified counter mode
34  *@param        K, the dedicated key (its size must be equal to the block size of E)
35  *@param        E, the block cipher context
36  *@param        inputBlock, the input block (its size must be equal to the block size of E)
37  *@param        nb, the number of wanted output blocks
38  *@param        counterValues, the counter values (its size must be nbOutputBlock*sizeBlock)
39  *@return       1 if the output blocks have been produced, 0 in the other cases.
40  */
41 int SOBMMO::initialize(const byte* K, BlockCipher* E,const byte* inputBlock,int nb,const byte* counterValues){
42   int i; // iterator
43   char hexstr[1024];
44   byte buf[16];
45
46   sizeBlock=E->blockSize();
47   nbOutputBlocks=nb;
48
49
50   // allocate memory for the output blocks
51   outputBlocks=(byte *)malloc(sizeBlock*nbOutputBlocks);
52   if(outputBlocks==NULL){
53     return 0;
54   }
55
56   // debug traces
57   pskConvertHex((char *)K, (char *)&hexstr, sizeBlock);
58   DEBUG2("SOBMMO::initialize: K=");
59   DEBUG2((char *)&hexstr);
60
61   pskConvertHex((char *)inputBlock, (char *)&hexstr, sizeBlock);
62   DEBUG2("SOBMMO::initialize: inputBlock=");
63   DEBUG2((char *)&hexstr);
64
65   pskConvertHex((char *)counterValues, (char *)&hexstr, sizeBlock*nbOutputBlocks);
66   DEBUG2("SOBMMO::initialize: counterValues=");
67   DEBUG2((char *)&hexstr);
68
69   E->makeKey(K,sizeBlock,DIR_ENCRYPT);
70   E->encrypt(inputBlock,outputBlocks);
71
72   // duplicate the first result
73   for(i=1;i<nbOutputBlocks;i++)
74     {
75       memcpy(outputBlocks+i*sizeBlock,outputBlocks,sizeBlock);
76     }
77
78   pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
79   DEBUG2("SOBMMO::initialize: outputBlocks before XOR=");
80   DEBUG2((char *)&hexstr);
81
82   // XOR counter values
83   for(i=0;i<(nbOutputBlocks*sizeBlock);i++)
84     {
85       *(outputBlocks+i)=(*(outputBlocks+i))^(*(counterValues+i));
86     }
87
88   pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
89   DEBUG2("SOBMMO::initialize: outputBlocks after XOR=");
90   DEBUG2((char *)&hexstr);
91
92   // in order to check that AES(K,M) is valid
93   E->encrypt(outputBlocks,buf);
94   pskConvertHex((char *)buf, (char *)&hexstr, 16);
95   DEBUG2("SOBMMO::initialize: buf=");
96   DEBUG2((char *)&hexstr);
97
98   // produce each output block
99   for(i=0;i<nbOutputBlocks;i++)
100     {
101       E->encrypt(outputBlocks+i*sizeBlock,outputBlocks+i*sizeBlock); // Be careful, pt=ct !!! TBTested
102     }
103
104   pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
105   DEBUG2("SOBMMO::initialize: produced output blocks=");
106   DEBUG2((char *)&hexstr);
107
108   return 1;
109
110 }
111
112
113 /**
114  *@memo         this function returns an output block
115  *@param        id, the number of the wanted output block (the numerotation begins at 1 !!)
116  */
117 byte* SOBMMO::getOutputBlock(int id){
118   byte* output=NULL;
119
120   if(id<1 || id>nbOutputBlocks) {
121     return NULL;
122   }
123
124   output=(byte*)malloc(sizeBlock);
125   if(output==NULL){
126     return NULL;
127   }
128   memcpy(output,outputBlocks+(id-1)*sizeBlock,sizeBlock);
129   return output;
130 }