~fractalcat/gearmand/docfixes

« back to all changes in this revision

Viewing changes to libhashkit/aes.cc

  • Committer: Brian Aker
  • Date: 2012-12-13 11:44:26 UTC
  • mto: (621.4.66 workspace)
  • mto: This revision was merged to the branch mainline in revision 676.
  • Revision ID: brian@tangent.org-20121213114426-lnrt6aysy7lqc01h
Adding support for deriving the unique value based on the data that is supplied by the client.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
2
 * 
 
3
 *  Libhashkit library
 
4
 *
 
5
 *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
 
6
 *
 
7
 *  Redistribution and use in source and binary forms, with or without
 
8
 *  modification, are permitted provided that the following conditions are
 
9
 *  met:
 
10
 *
 
11
 *      * Redistributions of source code must retain the above copyright
 
12
 *  notice, this list of conditions and the following disclaimer.
 
13
 *
 
14
 *      * Redistributions in binary form must reproduce the above
 
15
 *  copyright notice, this list of conditions and the following disclaimer
 
16
 *  in the documentation and/or other materials provided with the
 
17
 *  distribution.
 
18
 *
 
19
 *      * The names of its contributors may not be used to endorse or
 
20
 *  promote products derived from this software without specific prior
 
21
 *  written permission.
 
22
 *
 
23
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
24
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
25
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
26
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
27
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
28
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
29
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
30
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
31
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
32
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
33
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
34
 *
 
35
 */
 
36
 
 
37
 
 
38
#include "libhashkit/common.h"
 
39
 
 
40
#include "libhashkit/rijndael.hpp"
 
41
 
 
42
#include <cstring>
 
43
 
 
44
#define AES_KEY_LENGTH 256               /* 128, 192, 256 */
 
45
#define AES_BLOCK_SIZE 16
 
46
 
 
47
enum encrypt_t
 
48
{
 
49
  AES_ENCRYPT,
 
50
  AES_DECRYPT
 
51
};
 
52
 
 
53
struct _key_t {
 
54
  int nr;
 
55
  uint32_t rk[4*(AES_MAXNR +1)];
 
56
};
 
57
 
 
58
struct aes_key_t {
 
59
  _key_t encode_key;
 
60
  _key_t decode_key;
 
61
};
 
62
 
 
63
aes_key_t* aes_create_key(const char *key, const size_t key_length)
 
64
{
 
65
  aes_key_t* _aes_key= (aes_key_t*)calloc(1, sizeof(aes_key_t));
 
66
  if (_aes_key)
 
67
  {
 
68
    uint8_t rkey[AES_KEY_LENGTH/8];
 
69
    uint8_t *rkey_end= rkey +AES_KEY_LENGTH/8;
 
70
    const char *key_end= key +key_length;
 
71
 
 
72
    memset(rkey, 0, sizeof(rkey));      /* Set initial key  */
 
73
 
 
74
    uint8_t *ptr= rkey;
 
75
    const char* sptr= key;
 
76
    for (; sptr < key_end; ptr++,sptr++)
 
77
    {
 
78
      if (ptr == rkey_end)
 
79
      {
 
80
        ptr= rkey;  /*  Just loop over tmp_key until we used all key */
 
81
      }
 
82
      *ptr^= (uint8_t) *sptr;
 
83
    }
 
84
 
 
85
    _aes_key->decode_key.nr= rijndaelKeySetupDec(_aes_key->decode_key.rk, rkey, AES_KEY_LENGTH);
 
86
    _aes_key->encode_key.nr= rijndaelKeySetupEnc(_aes_key->encode_key.rk, rkey, AES_KEY_LENGTH);
 
87
  }
 
88
 
 
89
  return _aes_key;
 
90
}
 
91
 
 
92
aes_key_t* aes_clone_key(aes_key_t *_aes_key)
 
93
{
 
94
  if (_aes_key == NULL)
 
95
  {
 
96
    return NULL;
 
97
  }
 
98
 
 
99
  aes_key_t* _aes_clone_key= (aes_key_t*)calloc(1, sizeof(aes_key_t));
 
100
  if (_aes_clone_key)
 
101
  {
 
102
    memcpy(_aes_clone_key, _aes_key, sizeof(aes_key_t));
 
103
  }
 
104
 
 
105
  return _aes_clone_key;
 
106
}
 
107
 
 
108
hashkit_string_st* aes_encrypt(aes_key_t *_aes_key,
 
109
                               const char* source, size_t source_length)
 
110
{
 
111
  if (_aes_key == NULL)
 
112
  {
 
113
    return NULL;
 
114
  }
 
115
 
 
116
  size_t num_blocks= source_length/AES_BLOCK_SIZE;
 
117
 
 
118
  hashkit_string_st* destination= hashkit_string_create(source_length);
 
119
  if (destination)
 
120
  {
 
121
    char *dest= hashkit_string_c_str_mutable(destination);
 
122
 
 
123
    for (size_t x= num_blocks; x > 0; x--)   /* Encode complete blocks */
 
124
    { 
 
125
      rijndaelEncrypt(_aes_key->encode_key.rk, _aes_key->encode_key.nr, (const uint8_t*) source,
 
126
                      (uint8_t*) dest);
 
127
      source+= AES_BLOCK_SIZE;
 
128
      dest+= AES_BLOCK_SIZE;
 
129
    }
 
130
 
 
131
    uint8_t block[AES_BLOCK_SIZE];
 
132
    char pad_len= AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks);
 
133
    memcpy(block, source, 16 -pad_len);
 
134
    memset(block + AES_BLOCK_SIZE -pad_len, pad_len, pad_len);
 
135
    rijndaelEncrypt(_aes_key->encode_key.rk, _aes_key->encode_key.nr, block, (uint8_t*) dest);
 
136
    hashkit_string_set_length(destination, AES_BLOCK_SIZE*(num_blocks + 1));
 
137
  }
 
138
 
 
139
  return destination;
 
140
}
 
141
 
 
142
hashkit_string_st* aes_decrypt(aes_key_t *_aes_key,
 
143
                               const char* source, size_t source_length)
 
144
{
 
145
  if (_aes_key == NULL)
 
146
  {
 
147
    return NULL;
 
148
  }
 
149
 
 
150
  size_t num_blocks= source_length/AES_BLOCK_SIZE;
 
151
  if ((source_length != num_blocks*AES_BLOCK_SIZE) or num_blocks ==0 )
 
152
  {
 
153
    return NULL;
 
154
  }
 
155
 
 
156
  hashkit_string_st* destination= hashkit_string_create(source_length);
 
157
  if (destination)
 
158
  {
 
159
    char *dest= hashkit_string_c_str_mutable(destination);
 
160
 
 
161
    for (size_t x = num_blocks-1; x > 0; x--)
 
162
    {
 
163
      rijndaelDecrypt(_aes_key->decode_key.rk, _aes_key->decode_key.nr, (const uint8_t*) source, (uint8_t*) dest);
 
164
      source+= AES_BLOCK_SIZE;
 
165
      dest+= AES_BLOCK_SIZE;
 
166
    }
 
167
 
 
168
    uint8_t block[AES_BLOCK_SIZE];
 
169
    rijndaelDecrypt(_aes_key->decode_key.rk, _aes_key->decode_key.nr, (const uint8_t*) source, block);
 
170
    /* Use last char in the block as size */
 
171
    unsigned int pad_len= (unsigned int) (unsigned char) block[AES_BLOCK_SIZE-1];
 
172
    if (pad_len > AES_BLOCK_SIZE)
 
173
    {
 
174
      hashkit_string_free(destination);
 
175
      return NULL;
 
176
    }
 
177
 
 
178
    /* We could also check whole padding but we do not really need this */
 
179
 
 
180
    memcpy(dest, block, AES_BLOCK_SIZE - pad_len);
 
181
    hashkit_string_set_length(destination, AES_BLOCK_SIZE*num_blocks - pad_len);
 
182
  }
 
183
 
 
184
  return destination;
 
185
}