DJI_Codec.cpp
Go to the documentation of this file.
00001 
00012 #include "DJI_Codec.h"
00013 #include "DJI_Link.h"
00014 #include "DJI_API.h"
00015 
00017 // BEGIN OF AES-256
00018 //
00019 /*
00020 *   Byte-oriented AES-256 implementation.
00021 *   All lookup tables replaced with 'on the fly' calculations.
00022 *
00023 *   Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
00024 *   Other contributors: Hal Finney
00025 *
00026 *   Permission to use, copy, modify, and distribute this software for any
00027 *   purpose with or without fee is hereby granted, provided that the above
00028 *   copyright notice and this permission notice appear in all copies.
00029 *
00030 *   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00031 *   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00032 *   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00033 *   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00034 *   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00035 *   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00036 *   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00037 */
00038 typedef struct tagAES256Context
00039 {
00040   unsigned char key[32];
00041   unsigned char enckey[32];
00042   unsigned char deckey[32];
00043 } aes256_context;
00044 
00045 #define F(x) (((x) << 1) ^ ((((x) >> 7) & 1) * 0x1b))
00046 #define FD(x) (((x) >> 1) ^ (((x)&1) ? 0x8d : 0))
00047 
00048 #define BACK_TO_TABLES
00049 #ifdef BACK_TO_TABLES
00050 
00051 const unsigned char sbox[256] = {
00052   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab,
00053   0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4,
00054   0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71,
00055   0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
00056   0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6,
00057   0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,
00058   0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45,
00059   0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
00060   0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44,
00061   0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a,
00062   0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49,
00063   0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
00064   0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25,
00065   0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e,
00066   0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1,
00067   0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
00068   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb,
00069   0x16
00070 };
00071 const unsigned char sboxinv[256] = {
00072   0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7,
00073   0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde,
00074   0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42,
00075   0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
00076   0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c,
00077   0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15,
00078   0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7,
00079   0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
00080   0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc,
00081   0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad,
00082   0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d,
00083   0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
00084   0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8,
00085   0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51,
00086   0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0,
00087   0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
00088   0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c,
00089   0x7d
00090 };
00091 
00092 #define rj_sbox(x) sbox[(x)]
00093 #define rj_sbox_inv(x) sboxinv[(x)]
00094 
00095 #else /* tableless subroutines */
00096 
00097 /* -------------------------------------------------------------------------- */
00098 unsigned char gf_alog(unsigned char x) // calculate anti-logarithm gen 3
00099 {
00100   unsigned char atb = 1, z;
00101 
00102   while (x--)
00103   {
00104     z = atb;
00105     atb <<= 1;
00106     if (z & 0x80)
00107       atb ^= 0x1b;
00108     atb ^= z;
00109   }
00110 
00111   return atb;
00112 } /* gf_alog */
00113 
00114 /* -------------------------------------------------------------------------- */
00115 unsigned char gf_log(unsigned char x) // calculate logarithm gen 3
00116 {
00117   unsigned char atb = 1, i = 0, z;
00118 
00119   do
00120   {
00121     if (atb == x)
00122       break;
00123     z = atb;
00124     atb <<= 1;
00125     if (z & 0x80)
00126       atb ^= 0x1b;
00127     atb ^= z;
00128   } while (++i > 0);
00129 
00130   return i;
00131 } /* gf_log */
00132 
00133 /* -------------------------------------------------------------------------- */
00134 unsigned char gf_mulinv(unsigned char x) // calculate multiplicative inverse
00135 {
00136   return (x) ? gf_alog(255 - gf_log(x)) : 0;
00137 } /* gf_mulinv */
00138 
00139 /* -------------------------------------------------------------------------- */
00140 unsigned char rj_sbox(unsigned char x)
00141 {
00142   unsigned char y, sb;
00143 
00144   sb = y = gf_mulinv(x);
00145   y = (y << 1) | (y >> 7);
00146   sb ^= y;
00147   y = (y << 1) | (y >> 7);
00148   sb ^= y;
00149   y = (y << 1) | (y >> 7);
00150   sb ^= y;
00151   y = (y << 1) | (y >> 7);
00152   sb ^= y;
00153 
00154   return (sb ^ 0x63);
00155 } /* rj_sbox */
00156 
00157 /* -------------------------------------------------------------------------- */
00158 unsigned char rj_sbox_inv(unsigned char x)
00159 {
00160   unsigned char y, sb;
00161 
00162   y = x ^ 0x63;
00163   sb = y = (y << 1) | (y >> 7);
00164   y = (y << 2) | (y >> 6);
00165   sb ^= y;
00166   y = (y << 3) | (y >> 5);
00167   sb ^= y;
00168 
00169   return gf_mulinv(sb);
00170 } /* rj_sbox_inv */
00171 
00172 #endif
00173 
00174 /* -------------------------------------------------------------------------- */
00175 unsigned char rj_xtime(unsigned char x)
00176 {
00177   return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);
00178 } /* rj_xtime */
00179 
00180 /* -------------------------------------------------------------------------- */
00181 void aes_subBytes(unsigned char *buf)
00182 {
00183   register unsigned char i = 16;
00184 
00185   while (i--) buf[i] = rj_sbox(buf[i]);
00186 } /* aes_subBytes */
00187 
00188 /* -------------------------------------------------------------------------- */
00189 void aes_subBytes_inv(unsigned char *buf)
00190 {
00191   register unsigned char i = 16;
00192 
00193   while (i--) buf[i] = rj_sbox_inv(buf[i]);
00194 } /* aes_subBytes_inv */
00195 
00196 /* -------------------------------------------------------------------------- */
00197 void aes_addRoundKey(unsigned char *buf, unsigned char *key)
00198 {
00199   register unsigned char i = 16;
00200 
00201   while (i--) buf[i] ^= key[i];
00202 } /* aes_addRoundKey */
00203 
00204 /* -------------------------------------------------------------------------- */
00205 void aes_addRoundKey_cpy(unsigned char *buf, unsigned char *key, unsigned char *cpk)
00206 {
00207   register unsigned char i = 16;
00208 
00209   while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i];
00210 } /* aes_addRoundKey_cpy */
00211 
00212 /* -------------------------------------------------------------------------- */
00213 void aes_shiftRows(unsigned char *buf)
00214 {
00215   register unsigned char i, j; /* to make it potentially parallelable :) */
00216 
00217   i = buf[1];
00218   buf[1] = buf[5];
00219   buf[5] = buf[9];
00220   buf[9] = buf[13];
00221   buf[13] = i;
00222   i = buf[10];
00223   buf[10] = buf[2];
00224   buf[2] = i;
00225   j = buf[3];
00226   buf[3] = buf[15];
00227   buf[15] = buf[11];
00228   buf[11] = buf[7];
00229   buf[7] = j;
00230   j = buf[14];
00231   buf[14] = buf[6];
00232   buf[6] = j;
00233 
00234 } /* aes_shiftRows */
00235 
00236 /* -------------------------------------------------------------------------- */
00237 void aes_shiftRows_inv(unsigned char *buf)
00238 {
00239   register unsigned char i, j; /* same as above :) */
00240 
00241   i = buf[1];
00242   buf[1] = buf[13];
00243   buf[13] = buf[9];
00244   buf[9] = buf[5];
00245   buf[5] = i;
00246   i = buf[2];
00247   buf[2] = buf[10];
00248   buf[10] = i;
00249   j = buf[3];
00250   buf[3] = buf[7];
00251   buf[7] = buf[11];
00252   buf[11] = buf[15];
00253   buf[15] = j;
00254   j = buf[6];
00255   buf[6] = buf[14];
00256   buf[14] = j;
00257 
00258 } /* aes_shiftRows_inv */
00259 
00260 /* -------------------------------------------------------------------------- */
00261 void aes_mixColumns(unsigned char *buf)
00262 {
00263   register unsigned char i, a, b, c, d, e;
00264 
00265   for (i = 0; i < 16; i += 4)
00266   {
00267     a = buf[i];
00268     b = buf[i + 1];
00269     c = buf[i + 2];
00270     d = buf[i + 3];
00271     e = a ^ b ^ c ^ d;
00272     buf[i] ^= e ^ rj_xtime(a ^ b);
00273     buf[i + 1] ^= e ^ rj_xtime(b ^ c);
00274     buf[i + 2] ^= e ^ rj_xtime(c ^ d);
00275     buf[i + 3] ^= e ^ rj_xtime(d ^ a);
00276   }
00277 } /* aes_mixColumns */
00278 
00279 /* -------------------------------------------------------------------------- */
00280 void aes_mixColumns_inv(unsigned char *buf)
00281 {
00282   register unsigned char i, a, b, c, d, e, x, y, z;
00283 
00284   for (i = 0; i < 16; i += 4)
00285   {
00286     a = buf[i];
00287     b = buf[i + 1];
00288     c = buf[i + 2];
00289     d = buf[i + 3];
00290     e = a ^ b ^ c ^ d;
00291     z = rj_xtime(e);
00292     x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));
00293     y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));
00294     buf[i] ^= x ^ rj_xtime(a ^ b);
00295     buf[i + 1] ^= y ^ rj_xtime(b ^ c);
00296     buf[i + 2] ^= x ^ rj_xtime(c ^ d);
00297     buf[i + 3] ^= y ^ rj_xtime(d ^ a);
00298   }
00299 } /* aes_mixColumns_inv */
00300 
00301 /* -------------------------------------------------------------------------- */
00302 void aes_expandEncKey(unsigned char *k, unsigned char *rc)
00303 {
00304   register unsigned char i;
00305 
00306   k[0] ^= rj_sbox(k[29]) ^ (*rc);
00307   k[1] ^= rj_sbox(k[30]);
00308   k[2] ^= rj_sbox(k[31]);
00309   k[3] ^= rj_sbox(k[28]);
00310   *rc = F(*rc);
00311 
00312   for (i = 4; i < 16; i += 4)
00313     k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
00314   k[16] ^= rj_sbox(k[12]);
00315   k[17] ^= rj_sbox(k[13]);
00316   k[18] ^= rj_sbox(k[14]);
00317   k[19] ^= rj_sbox(k[15]);
00318 
00319   for (i = 20; i < 32; i += 4)
00320     k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
00321 
00322 } /* aes_expandEncKey */
00323 
00324 /* -------------------------------------------------------------------------- */
00325 void aes_expandDecKey(unsigned char *k, unsigned char *rc)
00326 {
00327   unsigned char i;
00328 
00329   for (i = 28; i > 16; i -= 4)
00330     k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
00331 
00332   k[16] ^= rj_sbox(k[12]);
00333   k[17] ^= rj_sbox(k[13]);
00334   k[18] ^= rj_sbox(k[14]);
00335   k[19] ^= rj_sbox(k[15]);
00336 
00337   for (i = 12; i > 0; i -= 4)
00338     k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
00339 
00340   *rc = FD(*rc);
00341   k[0] ^= rj_sbox(k[29]) ^ (*rc);
00342   k[1] ^= rj_sbox(k[30]);
00343   k[2] ^= rj_sbox(k[31]);
00344   k[3] ^= rj_sbox(k[28]);
00345 } /* aes_expandDecKey */
00346 
00347 /* -------------------------------------------------------------------------- */
00348 void aes256_init(aes256_context *ctx, unsigned char *k)
00349 {
00350   unsigned char rcon = 1;
00351   register unsigned char i;
00352 
00353   for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];
00354   for (i = 8; --i;) aes_expandEncKey(ctx->deckey, &rcon);
00355 } /* aes256_init */
00356 
00357 /* -------------------------------------------------------------------------- */
00358 void aes256_done(aes256_context *ctx)
00359 {
00360   register unsigned char i;
00361 
00362   for (i = 0; i < sizeof(ctx->key); i++) ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
00363 } /* aes256_done */
00364 
00365 /* -------------------------------------------------------------------------- */
00366 void aes256_encrypt_ecb(aes256_context *ctx, unsigned char *buf)
00367 {
00368   unsigned char i, rcon;
00369 
00370   aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
00371   for (i = 1, rcon = 1; i < 14; ++i)
00372   {
00373     aes_subBytes(buf);
00374     aes_shiftRows(buf);
00375     aes_mixColumns(buf);
00376     if (i & 1)
00377     {
00378       aes_addRoundKey(buf, &ctx->key[16]);
00379     }
00380     else
00381     {
00382       aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
00383     }
00384   }
00385   aes_subBytes(buf);
00386   aes_shiftRows(buf);
00387   aes_expandEncKey(ctx->key, &rcon);
00388   aes_addRoundKey(buf, ctx->key);
00389 } /* aes256_encrypt */
00390 
00391 /* -------------------------------------------------------------------------- */
00392 void aes256_decrypt_ecb(aes256_context *ctx, unsigned char *buf)
00393 {
00394   unsigned char i, rcon;
00395 
00396   aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
00397   aes_shiftRows_inv(buf);
00398   aes_subBytes_inv(buf);
00399 
00400   for (i = 14, rcon = 0x80; --i;) 
00401   {
00402     if ((i & 1))
00403     {
00404       aes_expandDecKey(ctx->key, &rcon);
00405       aes_addRoundKey(buf, &ctx->key[16]);
00406     }
00407     else
00408       aes_addRoundKey(buf, ctx->key);
00409     aes_mixColumns_inv(buf);
00410     aes_shiftRows_inv(buf);
00411     aes_subBytes_inv(buf);
00412   }
00413   aes_addRoundKey(buf, ctx->key);
00414 } /* aes256_decrypt */
00415 
00416 // END OF AES-256
00417 
00419 uint16_t crc_tab16[] = {
00420   0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780,
00421   0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1,
00422   0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801,
00423   0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40,
00424   0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680,
00425   0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0,
00426   0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501,
00427   0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
00428   0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981,
00429   0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1,
00430   0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200,
00431   0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141,
00432   0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480,
00433   0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0,
00434   0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01,
00435   0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
00436   0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381,
00437   0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0,
00438   0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01,
00439   0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40,
00440   0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81,
00441   0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1,
00442   0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100,
00443   0x81c1, 0x8081, 0x4040,
00444 };
00445 
00446 uint32_t crc_tab32[] = {
00447   0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535,
00448   0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd,
00449   0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d,
00450   0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
00451   0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
00452   0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
00453   0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac,
00454   0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
00455   0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
00456   0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
00457   0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb,
00458   0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
00459   0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea,
00460   0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce,
00461   0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
00462   0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
00463   0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409,
00464   0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
00465   0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739,
00466   0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
00467   0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268,
00468   0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0,
00469   0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8,
00470   0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
00471   0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
00472   0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703,
00473   0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
00474   0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
00475   0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae,
00476   0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
00477   0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6,
00478   0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
00479   0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d,
00480   0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5,
00481   0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
00482   0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
00483   0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
00484 };
00485 
00486 const unsigned short CRC_INIT = 0x3AA3;
00487 
00488 uint16_t crc16_update(uint16_t crc, uint8_t ch)
00489 {
00490   uint16_t tmp;
00491   uint16_t msg;
00492 
00493   msg = 0x00ff & (uint16_t)ch;
00494   tmp = crc ^ msg;
00495   crc = (crc >> 8) ^ crc_tab16[tmp & 0xff];
00496 
00497   return crc;
00498 }
00499 
00500 uint32_t crc32_update(uint32_t crc, uint8_t ch)
00501 {
00502   uint32_t tmp;
00503   uint32_t msg;
00504 
00505   msg = 0x000000ffL & (uint32_t)ch;
00506   tmp = crc ^ msg;
00507   crc = (crc >> 8) ^ crc_tab32[tmp & 0xff];
00508   return crc;
00509 }
00510 
00511 uint16_t sdk_stream_crc16_calc(const uint8_t *pMsg, size_t nLen)
00512 {
00513   size_t i;
00514   uint16_t wCRC = CRC_INIT;
00515 
00516   for (i = 0; i < nLen; i++)
00517   {
00518     wCRC = crc16_update(wCRC, pMsg[i]);
00519   }
00520 
00521   return wCRC;
00522 }
00523 
00524 uint32_t sdk_stream_crc32_calc(const uint8_t *pMsg, size_t nLen)
00525 {
00526   size_t i;
00527   uint32_t wCRC = CRC_INIT;
00528 
00529   for (i = 0; i < nLen; i++)
00530   {
00531     wCRC = crc32_update(wCRC, pMsg[i]);
00532   }
00533 
00534   return wCRC;
00535 }
00536 
00552 typedef void (*ptr_aes256_codec)(aes256_context *ctx, unsigned char *buf);
00553 using namespace DJI::onboardSDK;
00554 
00555 void sdk_stream_prepare_lambda(SDKFilter *p_filter)
00556 {
00557   unsigned int bytes_to_move = sizeof(Header) - 1;
00558   unsigned int index_of_move = p_filter->recvIndex - bytes_to_move;
00559 
00560   memmove(p_filter->recvBuf, p_filter->recvBuf + index_of_move, bytes_to_move);
00561   memset(p_filter->recvBuf + bytes_to_move, 0, index_of_move);
00562   p_filter->recvIndex = bytes_to_move;
00563 }
00564 
00565 void encodeData(SDKFilter *p_filter, Header *p_head, ptr_aes256_codec codec_func)
00566 {
00567   aes256_context ctx;
00568   unsigned int buf_i;
00569   unsigned int loop_blk;
00570   unsigned int data_len;
00571   unsigned int data_idx;
00572   unsigned char *data_ptr;
00573 
00574   if (p_head->enc == 0)
00575     return;
00576   if (p_head->length == sizeof(Header))
00577     return;
00578   if (p_head->length <= sizeof(Header) + _SDK_CRC_DATA_SIZE)
00579     return;
00580 
00581   data_ptr = (unsigned char *)p_head + sizeof(Header);
00582   data_len = p_head->length - _SDK_CRC_DATA_SIZE - sizeof(Header);
00583   loop_blk = data_len / 16;
00584   data_idx = 0;
00585 
00586   aes256_init(&ctx, p_filter->sdkKey);
00587   for (buf_i = 0; buf_i < loop_blk; buf_i++)
00588   {
00589     codec_func(&ctx, data_ptr + data_idx);
00590     data_idx += 16;
00591   }
00592   aes256_done(&ctx);
00593 
00594   if (codec_func == aes256_decrypt_ecb)
00595     p_head->length = p_head->length - p_head->padding; // minus padding length;
00596 }
00597 
00598 void DJI::onboardSDK::CoreAPI::callApp(SDKFilter *p_filter)
00599 {
00600   // pass current data to handler
00601   Header *p_head = (Header *)p_filter->recvBuf;
00602   encodeData(p_filter, p_head, aes256_decrypt_ecb);
00603   appHandler((Header *)p_filter->recvBuf);
00604   sdk_stream_prepare_lambda(p_filter);
00605 }
00606 
00607 bool CoreAPI::decodeACKStatus(unsigned short ack)
00608 {
00609   switch (ack)
00610   {
00611     case ACK_COMMON_SUCCESS:
00612       API_LOG(serialDevice, STATUS_LOG, "SUCCESS.");
00613       return true;
00614     case ACK_COMMON_KEYERROR:
00615       API_LOG(serialDevice, ERROR_LOG, "Wrong encode Key, Activate again.");
00616       return false;
00617     case ACK_COMMON_NO_AUTHORIZATION:
00618       API_LOG(serialDevice, ERROR_LOG, "Please obtain control and retry.");
00619       return false;
00620     case ACK_COMMON_NO_RIGHTS:
00621       API_LOG(serialDevice, ERROR_LOG, "Need higher Level access.");
00622       return false;
00623     case ACK_COMMON_NO_RESPONSE:
00624       API_LOG(serialDevice, ERROR_LOG, "Check your Hardware connection and retry.");
00625       return false;
00626     default:
00627       API_LOG(serialDevice, ERROR_LOG, "Unkown ACK code: 0x%x", ack);
00628       return false;
00629   }
00630 }
00631 
00632 void sdk_stream_shift_data_lambda(SDKFilter *p_filter)
00633 {
00634   if (p_filter->recvIndex)
00635   {
00636     p_filter->recvIndex--;
00637     if (p_filter->recvIndex)
00638     {
00639       memmove(p_filter->recvBuf, p_filter->recvBuf + 1, p_filter->recvIndex);
00640     }
00641   }
00642 }
00643 
00645 void CoreAPI::storeData(SDKFilter *p_filter, unsigned char in_data)
00646 {
00647   if (p_filter->recvIndex < _SDK_MAX_RECV_SIZE)
00648   {
00649     p_filter->recvBuf[p_filter->recvIndex] = in_data;
00650     p_filter->recvIndex++;
00651   }
00652   else
00653   {
00654     API_LOG(serialDevice, ERROR_LOG, "buffer overflow");
00655     memset(p_filter->recvBuf, 0, p_filter->recvIndex);
00656     p_filter->recvIndex = 0;
00657   }
00658 }
00659 
00660 // this function will move the data part to buffer end,
00661 // head part will move left
00662 //
00663 //  1. there no re-use data
00664 //  |------------------------------------------| <= cache
00665 //                       ^
00666 //                       reuse_index
00667 //  [12345678][ data Part ]--------------------| 1. p_filter
00668 //  [12345678]---------------------[ data Part ] 2. move data to end
00669 //  [2345678]----------------------[ data Part ] 3. forward head
00670 //  [2345678]------------[ data need to re-use ] 4. final mem layout
00671 //
00672 //  2. already has re-use data
00673 //  |---------------------------------[rev data] <= cache
00674 //                  ^
00675 //                  reuse_index, the data already used
00676 //  [12345678][ data Part ]-----------[rev data] 1. p_filter
00677 //  [12345678]-----------[ data Part ][rev data] 2. move data to end
00678 //  [2345678]------------[ data Part ][rev data] 3. forward head
00679 //  [2345678]------------[ data need to re-use ] 4. final mem layout
00680 //
00681 // the re-use data will loop later
00682 
00683 void sdk_stream_update_reuse_part_lambda(SDKFilter *p_filter)
00684 {
00685   unsigned char *p_buf = p_filter->recvBuf;
00686   unsigned short bytes_to_move = p_filter->recvIndex - sizeof(Header);
00687   unsigned char *p_src = p_buf + sizeof(Header);
00688 
00689   unsigned short n_dest_index = p_filter->reuseIndex - bytes_to_move;
00690   unsigned char *p_dest = p_buf + n_dest_index;
00691 
00692   memmove(p_dest, p_src, bytes_to_move);
00693 
00694   p_filter->recvIndex = sizeof(Header);
00695   sdk_stream_shift_data_lambda(p_filter);
00696 
00697   p_filter->reuseIndex = n_dest_index;
00698   p_filter->reuseCount++;
00699 }
00700 
00701 void DJI::onboardSDK::CoreAPI::verifyData(SDKFilter *p_filter)
00702 {
00703   Header *p_head = (Header *)(p_filter->recvBuf);
00704   if (_SDK_CALC_CRC_TAIL(p_head, p_head->length) == 0)
00705   {
00706     callApp(p_filter);
00707   }
00708   else
00709   {
00711     sdk_stream_update_reuse_part_lambda(p_filter);
00712   }
00713 }
00714 
00715 void DJI::onboardSDK::CoreAPI::verifyHead(SDKFilter *p_filter)
00716 {
00717   Header *p_head = (Header *)(p_filter->recvBuf);
00718 
00719   if ((p_head->sof == _SDK_SOF) && (p_head->version == 0) &&
00720     (p_head->length < _SDK_MAX_RECV_SIZE) && (p_head->reversed0 == 0) &&
00721     (p_head->reversed1 == 0) && (_SDK_CALC_CRC_HEAD(p_head, sizeof(Header)) == 0))
00722   {
00723     // check if this head is a ack or simple package
00724     if (p_head->length == sizeof(Header))
00725     {
00726       callApp(p_filter);
00727     }
00728   }
00729   else
00730   {
00731     sdk_stream_shift_data_lambda(p_filter);
00732   }
00733 }
00734 
00735 void DJI::onboardSDK::CoreAPI::checkStream(SDKFilter *p_filter)
00736 {
00737   Header *p_head = (Header *)(p_filter->recvBuf);
00738 
00739   if (p_filter->recvIndex < sizeof(Header))
00740   {
00741     // Continue receive data, nothing to do
00742     return;
00743   }
00744   else if (p_filter->recvIndex == sizeof(Header))
00745   {
00746     // recv a full-head
00747     verifyHead(p_filter);
00748   }
00749   else if (p_filter->recvIndex == p_head->length)
00750   {
00751     verifyData(p_filter);
00752   }
00753 }
00754 
00755 void DJI::onboardSDK::CoreAPI::streamHandler(SDKFilter *p_filter, unsigned char in_data)
00756 {
00757   storeData(p_filter, in_data);
00758   checkStream(p_filter);
00759 }
00760 
00761 void DJI::onboardSDK::CoreAPI::byteHandler(const uint8_t in_data)
00762 {
00763   filter.reuseCount = 0;
00764   filter.reuseIndex = _SDK_MAX_RECV_SIZE;
00765 
00766   streamHandler(&filter, in_data);
00767 
00790   if (filter.reuseCount != 0)
00791   {
00792     while (filter.reuseIndex < _SDK_MAX_RECV_SIZE)
00793     {
00799       streamHandler(&filter, filter.recvBuf[filter.reuseIndex++]);
00800     }
00801     filter.reuseCount = 0;
00802   }
00803 }
00804 
00805 // Implement stream handler here
00806 void CoreAPI::byteStreamHandler(uint8_t *buffer __UNUSED, size_t size __UNUSED){}
00807 
00808 void calculateCRC(void *p_data)
00809 {
00810   Header *p_head = (Header *)p_data;
00811   unsigned char *p_byte = (unsigned char *)p_data;
00812   unsigned int index_of_crc2;
00813 
00814   if (p_head->sof != _SDK_SOF)
00815     return;
00816   if (p_head->version != 0)
00817     return;
00818   if (p_head->length > _SDK_MAX_RECV_SIZE)
00819     return;
00820   if (p_head->length > sizeof(Header) && p_head->length < _SDK_FULL_DATA_SIZE_MIN)
00821     return;
00822 
00823   p_head->crc = sdk_stream_crc16_calc(p_byte, _SDK_HEAD_DATA_LEN);
00824 
00825   if (p_head->length >= _SDK_FULL_DATA_SIZE_MIN)
00826   {
00827     index_of_crc2 = p_head->length - _SDK_CRC_DATA_SIZE;
00828     _SDK_U32_SET(p_byte + index_of_crc2, sdk_stream_crc32_calc(p_byte, index_of_crc2));
00829   }
00830 }
00831 
00832 void transformTwoByte(const char *pstr, unsigned char *pdata)
00833 {
00834   int i;
00835   char temp_area[3];
00836   unsigned int temp8;
00837   temp_area[0] = temp_area[1] = temp_area[2] = 0;
00838 
00839   for (i = 0; i < 32; i++)
00840   {
00841     temp_area[0] = pstr[0];
00842     temp_area[1] = pstr[1];
00843     sscanf(temp_area, "%x", &temp8);
00844     pdata[i] = temp8;
00845     pstr += 2;
00846   }
00847 }
00848 
00849 unsigned short DJI::onboardSDK::CoreAPI::encrypt(unsigned char *pdest,
00850     const unsigned char *psrc,
00851     unsigned short w_len, unsigned char is_ack,
00852     unsigned char is_enc, unsigned char session_id,
00853     unsigned short seq_num)
00854 {
00855   unsigned short data_len;
00856 
00857   Header *p_head = (Header *)pdest;
00858 
00859   if (w_len > 1024)
00860     return 0;
00861 
00862   if (filter.encode == 0 && is_enc)
00863   {
00864     API_LOG(serialDevice, ERROR_LOG,
00865         "Can not send encode data, Please activate your device to get an available key.\n");
00866     return 0;
00867   }
00868   if (w_len == 0 || psrc == 0)
00869     data_len = (unsigned short)sizeof(Header);
00870   else
00871     data_len = (unsigned short)sizeof(Header) + _SDK_CRC_DATA_SIZE + w_len;
00872 
00873   if (is_enc)
00874     data_len = data_len + (16 - w_len % 16);
00875 
00876   API_LOG(serialDevice, DEBUG_LOG, "data len: %d\n", data_len);
00877 
00878   p_head->sof = _SDK_SOF;
00879   p_head->length = data_len;
00880   p_head->version = 0;
00881   p_head->sessionID = session_id;
00882   p_head->isAck = is_ack ? 1 : 0;
00883   p_head->reversed0 = 0;
00884 
00885   p_head->padding = is_enc ? (16 - w_len % 16) : 0;
00886   p_head->enc = is_enc ? 1 : 0;
00887   p_head->reversed1 = 0;
00888 
00889   p_head->sequenceNumber = seq_num;
00890   p_head->crc = 0;
00891 
00892   if (psrc && w_len)
00893     memcpy(pdest + sizeof(Header), psrc, w_len);
00894   encodeData(&filter, p_head, aes256_encrypt_ecb);
00895 
00896   calculateCRC(pdest);
00897 
00898   return data_len;
00899 }


dji_sdk_lib
Author(s):
autogenerated on Thu Jun 6 2019 17:55:25