Made it 2.0.0, and removed the changes that are in 1.1.x, as
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_psk / CTR.cpp
1 /*\r
2  * CTR.cpp\r
3  *\r
4  * The counter (CTR) mode of operation for block ciphers.\r
5  *\r
6  * @author Paulo S. L. M. Barreto\r
7  *\r
8  * This software is hereby placed in the public domain.\r
9  *\r
10  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
11  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
13  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
14  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
15  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
16  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
17  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
18  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
19  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
20  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
21  */\r
22 #include <assert.h>\r
23 #include <string.h>\r
24 #include <stdlib.h>\r
25 \r
26 #include "CTR.h"\r
27 \r
28 CTR::CTR(BlockCipher* E) {\r
29     this->E = E;\r
30     block_size = E->blockSize();\r
31     N = (byte *)calloc(block_size, 1);\r
32     S = (byte *)calloc(block_size, 1);\r
33     s = 0;\r
34 }\r
35 \r
36 CTR::~CTR() {\r
37     memset(N, (byte)0, block_size); free(N);\r
38     memset(S, (byte)0, block_size); free(S);\r
39 }\r
40 \r
41 void CTR::init(const byte* N) {\r
42     // initialize nonce:\r
43     memcpy(this->N, N, block_size);\r
44     E->encrypt(N, S); // S = E_K(N)\r
45     s = block_size;\r
46 }\r
47 \r
48 void CTR::update(const byte* M, uint m, byte* C) {\r
49     uint i = block_size - s;\r
50     uint j = 0;\r
51     while (m >= s) {\r
52         for (uint b = 0; b < s; b++) {\r
53             C[j + b] = (byte)(M[j + b] ^ S[i + b]);\r
54         }\r
55         // proceed to the next block:\r
56         m -= s;\r
57         j += s;\r
58         // increment the nonce:\r
59         for (uint n = block_size - 1; n >= 0; n--) {\r
60             if ((++N[n] & 0xff) != 0) {\r
61                 break;\r
62             }\r
63         }\r
64         E->encrypt(N, S);\r
65         s = block_size;\r
66         i = 0;\r
67     }\r
68     //assert(m < s);\r
69     // process remaining chunk (m bytes):\r
70     for (uint b = 0; b < m; b++) {\r
71         C[j + b] = (byte)(M[j + b] ^ S[i + b]);\r
72     }\r
73     s -= m;\r
74     //assert(0 < s && s <= block_size);\r
75 }\r
76 \r