for mostly educational purposes I am trying to understand how the key wrap algorithm works for encryption keys on RT117x.
I refer to section 11.5.2 of the Security Reference Manual, where algorithms are given in c for both wrapping and unwrapping keys.
Specifically: I have a properly functioning board with an encrypted FW, I have the wrapped keyblob file that it uses, and I have the KEK that I used to create said keyblob.
The key used, given as input to the image_enc tool is ffeeddccbbaa99887766554433221100
What I want to try to do is to try to unwrap "by hand" the keyblob
I transcribed the C functions do_aes128_key_unwrap() which doesn't work though, I tried some key permutations:
00112233445566778899aabbccddeeff
3322110077665544bbaa9988ffeeddcc
ffeeddccbbaa99887766554433221100
ccddeeff8899aabb4455667700112233
To implement the InvCipher() function (not described in the manual) I used this:
#include <openssl/evp.h>
void InvCipher(unsigned char *in, unsigned char *expanded_kek, int rounds, unsigned char *out) {
EVP_CIPHER_CTX *ctx;
int len;
ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, expanded_kek, NULL);
EVP_DecryptUpdate(ctx, out, &len, in, 16);
EVP_CIPHER_CTX_free(ctx);
}
Is this correct? If not, could you illustrate to me what the implementation of the function should be?
I used ECB since this function was created to decipher a single block, though if it's wrong let me know.
Another question: the manual refers in multiple places to RFC3394. I find these lines in the algorithm comments, though:
// step 1: initialize variables
// set A = C[0]
// for i = 1 to n
// R[i] = C[i]
// step 2: calculate intermediate values
// for j = 5 to 0
// for i = n to 1
// B = AES‐1(K, (A ^ (n*j+i) | R[i])
// A = MSB(64, B)
// R[i] = LSB(64, B)
// step 3: output the results
// if A == IV
// then
// for i = 1 to n
// P[i] = R[i]
// else
// return an error
But in section 2.2.2 of RFC3394 the same steps are described differently:
1) Initialize variables.
Set A[s] = C[0] where s = 6n
For i = 1 to n
R[s][i] = C[i]
2) Calculate the intermediate values.
For t = s to 1
A[t-1] = MSB(64, AES-1(K, ((A[t] ^ t) | R[t][n]))
R[t-1][1] = LSB(64, AES-1(K, ((A[t]^t) | R[t][n]))
For i = 2 to n
R[t-1][i] = R[t][i-1]
3) Output the results.
If A[0] is an appropriate initial value (see 2.2.3),
Then
For i = 1 to n
P[i] = R[0][i]
Else
Return an error
So is the algorithm described in the manual adherent to RFC3394 or not?
Finally, I found the sources of a version of 'image_enc' (here https://community.nxp.com/t5/i-MX-RT/image-enc2-zip-download/m-p/1174943#M10980) which though doesn't seem related to the version I have (Bundled in Provisioning tool 6)
Package: image_enc
Version: 1.0.0
Description: AES encryption utility
License: LA_OPT_NXP_SOFTWARE_License
License description: NXP proprietary
Distribution Type: Binary
Location: \tools\image_enc
can you get me the sources of this version as well?
best regards
Max