This code is supposed to implement RFC 3394 which also described in this PDF at page 11.
Are there any weak places or formatting issues in attached source? Or maybe some places are not explicit enough?
void wrap( const unsigned char *key, const unsigned char *plaintext, unsigned int plaintext_length,
unsigned char *ciphertext, unsigned int *ciphertext_length, unsigned int semiblocksize)
{
int i, j, k;
unsigned int n, t, tt;
unsigned char *A, B[16], *R;
int targetlevel = 0, p = semiblocksize;
while (p >>= 1) ++targetlevel;
n = plaintext_length >> targetlevel;
A = B;
memset(A, 0xa6, semiblocksize);
memcpy(ciphertext+semiblocksize, plaintext, plaintext_length);
for(j=0, t=1; j<=5; j++)
{
for(i=1, R=ciphertext+semiblocksize; i<=n; i++, t++, R+=semiblocksize)
{
memcpy(B+semiblocksize, R, semiblocksize);
AES128_ECB_encrypt(B, key, B);
for(k=semiblocksize - 1, tt=t; (k>=0) && (tt>0); k--, tt>>=semiblocksize)
{
A[k] ^= (unsigned char) (tt & 0xFF);
}
memcpy(R, B+semiblocksize, semiblocksize);
}
}
memcpy(ciphertext, A, semiblocksize);
*ciphertext_length = plaintext_length + semiblocksize;
}
I know, that ECB mode should not be used in production, but this is only for ensuring output correctness by checking coincidence with the RFC.