RDK Documentation (Open Sourced RDK Components)
mfrCrypto.c
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 
21 /**
22 * @defgroup iarmmgrs
23 * @{
24 * @defgroup mfr
25 * @{
26 **/
27 
28 
29 
30 #include <string.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <sys/time.h>
34 #include <openssl/aes.h>
35 #include "mfrCrypto.h"
36 #include "safec_lib.h"
37 
38 #define MFR_CRYPTO_KEY_LENGTH 16
39 #define MFR_CRYPTO_IVEC_LENGTH 16
40 
41 static mfrSerializedData_t serialNumber;
42 
43 static void mfr_create_key(const mfrSerializedData_t * pSerialNumber, unsigned char * keybuf, unsigned char * ivec)
44 {// this function should be static
45 
46  int i = 0, j = 0, k = 0, keylen = pSerialNumber->bufLen;
47  unsigned char normalizedkeybuf[MFR_CRYPTO_KEY_LENGTH] = {0};
48  unsigned char refkey[MFR_CRYPTO_KEY_LENGTH] = {0xD6, 0xC1, 0x5C, 0x1E, 0x1D, 0x64, 0x2D, 0x44,
49  0x68, 0x5C, 0xCE, 0xA0, 0x8D, 0x9F, 0x85, 0xCB};
50  unsigned char digkey[MFR_CRYPTO_KEY_LENGTH] = {0x2D, 0x6C, 0x1B, 0xFB, 0x7B, 0x86, 0x87, 0x35,
51  0xD0, 0x81, 0xD9, 0x6D, 0x25, 0x2B, 0xFB, 0xF1};
52  errno_t safec_rc = -1;
53 
54  if(keylen > MFR_CRYPTO_KEY_LENGTH) keylen = MFR_CRYPTO_KEY_LENGTH;
55  if(keylen <= 0) keylen = 1;
56  safec_rc = memset_s(keybuf, MFR_CRYPTO_KEY_LENGTH, 0, MFR_CRYPTO_KEY_LENGTH);
57  ERR_CHK(safec_rc);
58  // normalize the key strength
59  for(i = 0, k = 0; i < MFR_CRYPTO_KEY_LENGTH; i+= keylen, k = !k)
60  {
61  for(j = 0; (j < keylen) && ((j+i) < MFR_CRYPTO_KEY_LENGTH); j++)
62  {
63  unsigned char ix = (unsigned char)((j+7)%keylen);
64  unsigned char ir = (unsigned char)((j+3)%MFR_CRYPTO_KEY_LENGTH);
65  unsigned char cSN = (pSerialNumber->buf[ix]);
66 
67  if(0==cSN) cSN = refkey[ir];
68 
69  if(k)
70  {
71  normalizedkeybuf[i+j] = (cSN^0xFF);
72  }
73  else
74  {
75  normalizedkeybuf[i+j] = (cSN);
76  }
77  }
78  }
79 
80  // create a digested version of the normalized key
81  {
82  AES_KEY ctx;
83  unsigned char digestkeybuf[MFR_CRYPTO_KEY_LENGTH] = {0};
84  unsigned char iv[AES_BLOCK_SIZE] = {0};
85 
86  safec_rc = memcpy_s(digestkeybuf, keylen, pSerialNumber->buf, keylen);
87  if(safec_rc != EOK)
88  {
89  ERR_CHK(safec_rc);
90  return;
91  }
92  for(i = 0; i < MFR_CRYPTO_KEY_LENGTH; i+= 1)
93  {
94  digestkeybuf[i] += (unsigned char)(digkey[i]+refkey[i]);
95  }
96 
97  /* set up the AES key structure */
98  AES_set_encrypt_key(digestkeybuf, 128, &ctx);
99  // generate the digested key
100  AES_cbc_encrypt(normalizedkeybuf, keybuf, AES_BLOCK_SIZE, &ctx, iv, AES_ENCRYPT);
101  // generate the digested ivec
102  AES_cbc_encrypt(keybuf, ivec, AES_BLOCK_SIZE, &ctx, iv, AES_ENCRYPT);
103  }
104 }
105 
106 mfrError_t mfrCrypto_init( const mfrSerializedData_t * pSerialNumber )
107 {
108  errno_t safec_rc = -1;
109 
110  if((NULL == pSerialNumber) || (NULL == pSerialNumber->buf) || (pSerialNumber->bufLen<= 0))
111  {
112  return mfrERR_INVALID_PARAM;
113  }
114  safec_rc = memcpy_s(&serialNumber, sizeof( mfrSerializedData_t ), pSerialNumber, sizeof( mfrSerializedData_t ));
115  if(safec_rc != EOK)
116  {
117  ERR_CHK(safec_rc);
118  return mfrERR_INVALID_PARAM;
119  }
120 
121  return mfrERR_NONE;
122 }
123 
124 mfrError_t mfrCrypto_term( )
125 {
126  return mfrERR_NONE;
127 }
128 
129 mfrError_t mfrCrypto_Encrypt(const mfrSerializedData_t * pPlainText, mfrSerializedData_t * pCipherText)
130 {// this function should be static
131 
132  AES_KEY ctx;
133  int count = 0;
134  unsigned char keybuf[MFR_CRYPTO_KEY_LENGTH];
135  unsigned char iv[AES_BLOCK_SIZE];
136  int nBytes = pPlainText->bufLen;
137  unsigned char * pbuf = (unsigned char *) pPlainText->buf;
138  unsigned char * cbuf = NULL;
139  errno_t safec_rc = -1;
140 
141  pCipherText->buf = NULL;
142 
143  // parameter check
144  if(NULL == pbuf) return mfrERR_INVALID_PARAM;
145 
146  // block size check
147  if(0 != (nBytes%AES_BLOCK_SIZE))
148  {
149  // fix block size
150  nBytes = ((nBytes/AES_BLOCK_SIZE)+1)*AES_BLOCK_SIZE;
151  pbuf = (unsigned char *)malloc(nBytes);
152  if(NULL == pbuf) return mfrERR_GENERAL;
153  safec_rc = memset_s(pbuf, nBytes, 0, nBytes);
154  ERR_CHK(safec_rc);
155 
156  safec_rc = memcpy_s(pbuf, nBytes, pPlainText->buf, pPlainText->bufLen);
157  if(safec_rc != EOK)
158  {
159  ERR_CHK(safec_rc);
160  if (pbuf)
161  free (pbuf);
162  return mfrERR_GENERAL;
163  }
164 
165  }
166  // allocate output buffer
167  pCipherText->buf = (char *)malloc(nBytes);
168  cbuf = (unsigned char *) pCipherText->buf;
169  // check for alloc failure
170  /* coverity fix - 13/5 */
171  if(NULL == cbuf)
172  {
173  /* coverity fix */
174  if( pbuf != (unsigned char *) pPlainText->buf ) free(pbuf);
175  return mfrERR_GENERAL;
176  }
177 
178  // redundant check for block size
179  if(0 != (nBytes%AES_BLOCK_SIZE))
180  {
181  return mfrERR_INVALID_PARAM;
182  }
183 
184  /* set up the AES key structure */
185  mfr_create_key(&serialNumber, keybuf, iv);
186  AES_set_encrypt_key(keybuf, 128, &ctx);
187 
188  /* encrypt the data */
189  while (count < nBytes)
190  {
191  /* encrypt the data */
192  AES_cbc_encrypt(pbuf+count, cbuf+count, AES_BLOCK_SIZE, &ctx, iv, AES_ENCRYPT);
193  count += AES_BLOCK_SIZE;
194  }
195 
196  // free any duplicate pbuf
197  if(pbuf != (unsigned char *) pPlainText->buf)
198  {
199  free(pbuf);
200  }
201 
202  pCipherText->bufLen = nBytes;
203 
204  // return success
205  return mfrERR_NONE;
206 }
207 
208 mfrError_t mfrCrypto_Decrypt(const mfrSerializedData_t * pCipherText, mfrSerializedData_t * pPlainText)
209 {// this function should be static
210 
211  AES_KEY ctx;
212  unsigned char keybuf[MFR_CRYPTO_KEY_LENGTH];
213  int count = 0;
214  unsigned char iv[AES_BLOCK_SIZE];
215  int nBytes = pCipherText->bufLen;
216  unsigned char * cbuf = (unsigned char *) pCipherText->buf;
217  unsigned char * pbuf = NULL;
218  errno_t safec_rc = -1;
219 
220  pPlainText->buf = NULL;
221 
222  // parameter check
223  if(NULL == cbuf) return mfrERR_INVALID_PARAM;
224 
225  // block size check
226  if(0 != (nBytes%AES_BLOCK_SIZE))
227  {
228  // fix block size
229  nBytes = ((nBytes/AES_BLOCK_SIZE)+1)*AES_BLOCK_SIZE;
230  cbuf = (unsigned char *)malloc(nBytes);
231  if(NULL == cbuf) return mfrERR_GENERAL;
232  safec_rc = memset_s(cbuf, nBytes, 0, nBytes);
233  ERR_CHK(safec_rc);
234 
235  safec_rc = memcpy_s(cbuf, nBytes, pCipherText->buf, pCipherText->bufLen);
236  if(safec_rc != EOK)
237  {
238  ERR_CHK(safec_rc);
239  if(cbuf)
240  free(cbuf);
241  return mfrERR_GENERAL;
242  }
243 
244  }
245  // allocate output buffer
246  pPlainText->buf = (char *)malloc(nBytes);
247  pbuf = (unsigned char*) pPlainText->buf;
248 
249  // check for alloc failure
250  /* coverity fix - 13/5 */
251  if(NULL == pbuf)
252  {
253  if( cbuf != (unsigned char*) pCipherText->buf ) free( cbuf );
254  return mfrERR_GENERAL;
255  }
256 
257  // redundant check for block size
258  if(0 != (nBytes%AES_BLOCK_SIZE))
259  {
260  return mfrERR_INVALID_PARAM;
261  }
262 
263  /* set up the AES key structure */
264  mfr_create_key(&serialNumber, keybuf, iv);
265  AES_set_decrypt_key(keybuf, 128, &ctx);
266 
267  /* decrypt the data */
268  while (count < nBytes)
269  {
270  /* decrypt the data */
271  AES_cbc_encrypt(cbuf+count, pbuf+count, AES_BLOCK_SIZE, &ctx, iv, AES_DECRYPT);
272  count += AES_BLOCK_SIZE;
273  }
274 
275  // free any duplicate cbuf
276  if(cbuf != (unsigned char*) pCipherText->buf)
277  {
278  free(cbuf);
279  }
280 
281  pPlainText->bufLen = nBytes;
282 
283  // return success
284  return mfrERR_NONE;
285 }
286 
287 
288 /** @} */
289 /** @} */
_mfrSerializedData_t
Definition: mfrTypes.h:50