Remove dynamic exceptions
[anna.git] / source / core / util / Encoder.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <stdlib.h>
10
11 #include <anna/core/functions.hpp>
12
13 #include <anna/core/util/Encoder.hpp>
14
15
16 using namespace std;
17 using namespace anna;
18
19 void Encoder::initialize()
20 {
21   srand(functions::second());
22 }
23
24 const EncodedData& Encoder::encode(const DataBlock& data)
25 noexcept(false) {
26   DES_cblock key [3];
27   DES_key_schedule* skey [3];
28
29   for(int i = 0; i < 3; i ++) {
30     DES_random_key(&key[i]);
31     skey [i] = &a_data.a_skey [i];
32
33     if(DES_set_key_checked(&key[i], skey [i]) < 0) {
34       string msg("anna::Encoder::encode | DataBlock: ");
35       msg += functions::asString(data);
36       msg += " | Error during key generation";
37       throw RuntimeException(msg, ANNA_FILE_LOCATION);
38     }
39   }
40
41   errno = 0;
42   anna_memset(&a_data.a_iv, 0, sizeof(DES_cblock));
43   const DataBlock& output = setDataBlock(data);
44   unsigned char* aux = (unsigned char*) output.getData();
45   DES_ede3_cbc_encrypt(aux, aux, output.getSize(), skey[0], skey[1], skey[2], &a_data.a_iv, DES_ENCRYPT);
46
47   if(errno != 0) {
48     string msg("anna::Encoder::encode | DataBlock: ");
49     msg += functions::asString(data);
50     msg += " | Encoding error";
51     throw RuntimeException(msg, ANNA_FILE_LOCATION);
52   }
53
54   return a_data;
55 }
56
57 //-------------------------------------------------------------------------------------------------
58 // (1) Elimina los 8 primeros bytes que tuvimos que poner de relleno en la codificacion.
59 //-------------------------------------------------------------------------------------------------
60 const DataBlock& Encoder::decode(const EncodedData& data)
61 noexcept(false) {
62   if(data.a_realSize <= 0) {
63     string msg("anna::Encoder::encode | Cannot decode an uninitialized data");
64     throw RuntimeException(msg, ANNA_FILE_LOCATION);
65   }
66
67   unsigned char* text = (unsigned char*) data.a_value.getData();
68   DES_key_schedule* skey [3];
69   DES_cblock* iv;
70   skey [0] = const_cast <DES_key_schedule*>(&data.a_skey [0]);
71   skey [1] = const_cast <DES_key_schedule*>(&data.a_skey [1]);
72   skey [2] = const_cast <DES_key_schedule*>(&data.a_skey [2]);
73   iv = const_cast <DES_cblock*>(&data.a_iv);
74   errno = 0;
75   DES_ede3_cbc_encrypt(text, text, data.a_value.getSize(), skey[0], skey[1], skey[2], iv, DES_DECRYPT);
76
77   if(errno != 0) {
78     string msg("anna::Encoder::encode | Decoding error | Block: ");
79     msg += functions::asString(data.a_value);
80     throw RuntimeException(msg, ANNA_FILE_LOCATION);
81   }
82
83   const_cast <EncodedData&>(data).a_value.remove(sizeof(DES_cblock));        // (1)
84
85   const_cast <EncodedData&>(data).a_value.allocate(data.a_realSize);
86
87   return data.a_value;
88 }
89
90 //-------------------------------------------------------------------------------------------------
91 // (1) Rellena los 8 primeros bytes que no sabemos interpretar correctamente, lo ponemos para
92 // poder ignorarlos al decodificar. Ver
93 // 'const_cast <EncodedData&> (data).a_value.remove (sizeof (DES_cblock));'
94 //-------------------------------------------------------------------------------------------------
95 DataBlock& Encoder::setDataBlock(const DataBlock& other)
96 noexcept(false) {
97   DataBlock& value = a_data.a_value;
98   int r;
99   value.clear();
100
101   for(r = 0; r < sizeof(DES_cblock); r ++)                                      // (1)
102     value += char(0xaa);
103
104   value += other;
105   r = (a_data.a_realSize = other.getSize()) % 8;
106
107   if(r > 0) {
108     for(r = 8 - r; r > 0; r --)
109       value += char(0xee);
110   }
111
112   return value;
113 }
114
115
116