summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbtools/crypto.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/imxtools/sbtools/crypto.cpp')
-rw-r--r--utils/imxtools/sbtools/crypto.cpp83
1 files changed, 77 insertions, 6 deletions
diff --git a/utils/imxtools/sbtools/crypto.cpp b/utils/imxtools/sbtools/crypto.cpp
index 35068c3e7d..5ccde27fdd 100644
--- a/utils/imxtools/sbtools/crypto.cpp
+++ b/utils/imxtools/sbtools/crypto.cpp
@@ -20,9 +20,81 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "crypto.h" 21#include "crypto.h"
22#include "misc.h" 22#include "misc.h"
23#include <cryptopp/modes.h>
24#include <cryptopp/aes.h>
23 25
24static enum crypto_method_t g_cur_method = CRYPTO_NONE; 26using namespace CryptoPP;
25static byte g_key[16]; 27
28namespace
29{
30
31enum crypto_method_t g_cur_method = CRYPTO_NONE;
32byte g_key[16];
33CBC_Mode<AES>::Encryption g_aes_enc;
34CBC_Mode<AES>::Decryption g_aes_dec;
35bool g_aes_enc_key_dirty; /* true of g_aes_enc key needs to be updated */
36bool g_aes_dec_key_dirty; /* same for g_aes_dec */
37
38int cbc_mac2(
39 const byte *in_data, /* Input data */
40 byte *out_data, /* Output data (or NULL) */
41 int nr_blocks, /* Number of blocks to encrypt/decrypt (one block=16 bytes) */
42 byte key[16], /* Key */
43 byte iv[16], /* Initialisation Vector */
44 byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */
45 bool encrypt /* 1 to encrypt, 0 to decrypt */
46 )
47{
48 /* encrypt */
49 if(encrypt)
50 {
51 /* update keys if neeeded */
52 if(g_aes_enc_key_dirty)
53 {
54 /* we need to provide an IV with the key, although we change it
55 * everytime we run the cipher anyway */
56 g_aes_enc.SetKeyWithIV(g_key, 16, iv, 16);
57 g_aes_enc_key_dirty = false;
58 }
59 g_aes_enc.Resynchronize(iv, 16);
60 byte tmp[16];
61 /* we need some output buffer, either a temporary one if we are CBC-MACing
62 * only, or use output buffer if available */
63 byte *out_ptr = (out_data == NULL) ? tmp : out_data;
64 while(nr_blocks-- > 0)
65 {
66 g_aes_enc.ProcessData(out_ptr, in_data, 16);
67 /* if this is the last block, copy CBC-MAC */
68 if(nr_blocks == 0 && out_cbc_mac)
69 memcpy(out_cbc_mac, out_ptr, 16);
70 /* if we are writing data to the output buffer, advance output pointer */
71 if(out_data != NULL)
72 out_ptr += 16;
73 in_data += 16;
74 }
75 return CRYPTO_ERROR_SUCCESS;
76 }
77 /* decrypt */
78 else
79 {
80 /* update keys if neeeded */
81 if(g_aes_dec_key_dirty)
82 {
83 /* we need to provide an IV with the key, although we change it
84 * everytime we run the cipher anyway */
85 g_aes_dec.SetKeyWithIV(g_key, 16, iv, 16);
86 g_aes_dec_key_dirty = false;
87 }
88 /* we cannot produce a CBC-MAC in decrypt mode, output buffer exists */
89 if(out_cbc_mac || out_data == NULL)
90 return CRYPTO_ERROR_INVALID_OP;
91 g_aes_dec.Resynchronize(iv, 16);
92 g_aes_dec.ProcessData(out_data, in_data, nr_blocks * 16);
93 return CRYPTO_ERROR_SUCCESS;
94 }
95}
96
97}
26 98
27int crypto_setup(struct crypto_key_t *key) 99int crypto_setup(struct crypto_key_t *key)
28{ 100{
@@ -31,6 +103,8 @@ int crypto_setup(struct crypto_key_t *key)
31 { 103 {
32 case CRYPTO_KEY: 104 case CRYPTO_KEY:
33 memcpy(g_key, key->u.key, 16); 105 memcpy(g_key, key->u.key, 16);
106 g_aes_dec_key_dirty = true;
107 g_aes_enc_key_dirty = true;
34 return CRYPTO_ERROR_SUCCESS; 108 return CRYPTO_ERROR_SUCCESS;
35 default: 109 default:
36 return CRYPTO_ERROR_BADSETUP; 110 return CRYPTO_ERROR_BADSETUP;
@@ -46,10 +120,7 @@ int crypto_apply(
46 bool encrypt) 120 bool encrypt)
47{ 121{
48 if(g_cur_method == CRYPTO_KEY) 122 if(g_cur_method == CRYPTO_KEY)
49 { 123 return cbc_mac2(in_data, out_data, nr_blocks, g_key, iv, out_cbc_mac, encrypt);
50 cbc_mac(in_data, out_data, nr_blocks, g_key, iv, out_cbc_mac, encrypt);
51 return CRYPTO_ERROR_SUCCESS;
52 }
53 else 124 else
54 return CRYPTO_ERROR_BADSETUP; 125 return CRYPTO_ERROR_BADSETUP;
55} 126}