diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index 1aea29f8c..4cb723d31 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -1476,6 +1476,10 @@ static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, #ifdef CYASSL_AESNI aes->use_aesni = 0; #endif /* CYASSL_AESNI */ + #ifdef CYASSL_AES_COUNTER + aes->left = 0; + #endif /* CYASSL_AES_COUNTER */ + aes->rounds = keylen/4 + 6; XMEMCPY(rk, userKey, keylen); @@ -2129,15 +2133,39 @@ static INLINE void IncrementAesCounter(byte* inOutCtr) void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / AES_BLOCK_SIZE; + byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; - while (blocks--) { + /* consume any unused bytes left in aes->tmp */ + while (aes->left && sz) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + sz--; + } + + /* do as many block size ops as possible */ + while (sz >= AES_BLOCK_SIZE) { AesEncrypt(aes, (byte*)aes->reg, out); IncrementAesCounter((byte*)aes->reg); xorbuf(out, in, AES_BLOCK_SIZE); out += AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + sz -= AES_BLOCK_SIZE; + aes->left = 0; + } + + /* handle non block size remaining and sotre unused byte count in left */ + if (sz) { + AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp); + IncrementAesCounter((byte*)aes->reg); + + aes->left = AES_BLOCK_SIZE; + tmp = (byte*)aes->tmp; + + while (sz--) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + } } } diff --git a/ctaocrypt/src/pkcs7.c b/ctaocrypt/src/pkcs7.c index e9a797491..f025c8e0b 100644 --- a/ctaocrypt/src/pkcs7.c +++ b/ctaocrypt/src/pkcs7.c @@ -166,6 +166,7 @@ int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz) } XMEMCPY(pkcs7->publicKey, dCert.publicKey, dCert.pubKeySize); pkcs7->publicKeySz = dCert.pubKeySize; + XMEMCPY(pkcs7->issuerHash, dCert.issuerHash, SHA_SIZE); pkcs7->issuer = dCert.issuerRaw; pkcs7->issuerSz = dCert.issuerRawLen; XMEMCPY(pkcs7->issuerSn, dCert.serial, dCert.serialSz); @@ -1126,8 +1127,6 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, byte issuerHash[SHA_DIGEST_SIZE]; mp_int serialNum; - DecodedCert decoded; - int encryptedKeySz, keySz; byte tmpIv[DES_BLOCK_SIZE]; byte encryptedKey[MAX_ENCRYPTED_KEY_SZ]; @@ -1147,14 +1146,6 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, output == NULL || outputSz == 0) return BAD_FUNC_ARG; - /* parse recipient cert */ - InitDecodedCert(&decoded, pkcs7->singleCert, pkcs7->singleCertSz, 0); - ret = ParseCert(&decoded, CA_TYPE, NO_VERIFY, 0); - if (ret < 0) { - FreeDecodedCert(&decoded); - return ret; - } - /* load private key */ InitRsaKey(&privKey, 0); ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey, @@ -1230,7 +1221,7 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, return ASN_PARSE_E; /* if we found correct recipient, issuer hashes will match */ - if (XMEMCMP(issuerHash, decoded.issuerHash, SHA_DIGEST_SIZE) == 0) { + if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) { recipFound = 1; } @@ -1304,7 +1295,7 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, /* decrypt encryptedKey */ keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz, &decryptedKey, &privKey); - if (keySz < 0) + if (keySz <= 0) return keySz; /* decrypt encryptedContent */ diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 92099ba24..293879c03 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -1916,6 +1916,12 @@ int aes_test(void) 0x79,0x21,0x70,0xa0,0xf3,0x00,0x9c,0xee }; + const byte oddCipher[] = + { + 0xb9,0xd7,0xcb,0x08,0xb0,0xe1,0x7b,0xa0, + 0xc2 + }; + AesSetKeyDirect(&enc, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); /* Ctr only uses encrypt, even on key setup */ AesSetKeyDirect(&dec, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); @@ -1928,6 +1934,30 @@ int aes_test(void) if (memcmp(cipher, ctrCipher, AES_BLOCK_SIZE*4)) return -67; + + /* let's try with just 9 bytes, non block size test */ + AesSetKeyDirect(&enc, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); + /* Ctr only uses encrypt, even on key setup */ + AesSetKeyDirect(&dec, ctrKey, AES_BLOCK_SIZE, ctrIv, AES_ENCRYPTION); + + AesCtrEncrypt(&enc, cipher, ctrPlain, 9); + AesCtrEncrypt(&dec, plain, cipher, 9); + + if (memcmp(plain, ctrPlain, 9)) + return -68; + + if (memcmp(cipher, ctrCipher, 9)) + return -69; + + /* and an additional 9 bytes to reuse tmp left buffer */ + AesCtrEncrypt(&enc, cipher, ctrPlain, 9); + AesCtrEncrypt(&dec, plain, cipher, 9); + + if (memcmp(plain, ctrPlain, 9)) + return -70; + + if (memcmp(cipher, oddCipher, 9)) + return -71; } #endif /* CYASSL_AES_COUNTER */ diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index 37861903e..e280e006b 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -92,6 +92,9 @@ typedef struct Aes { word32 magic; /* using cavium magic */ word64 contextHandle; /* nitrox context memory handle */ #endif +#ifdef CYASSL_AES_COUNTER + word32 left; /* unsued bytes left from last call */ +#endif } Aes; diff --git a/cyassl/ctaocrypt/pkcs7.h b/cyassl/ctaocrypt/pkcs7.h index 8ff9c281f..b4313f399 100644 --- a/cyassl/ctaocrypt/pkcs7.h +++ b/cyassl/ctaocrypt/pkcs7.h @@ -65,25 +65,26 @@ typedef struct PKCS7Attrib { typedef struct PKCS7 { - byte* content; /* inner content, not owner */ - word32 contentSz; /* content size */ - int contentOID; /* PKCS#7 content type OID sum */ + byte* content; /* inner content, not owner */ + word32 contentSz; /* content size */ + int contentOID; /* PKCS#7 content type OID sum */ RNG* rng; int hashOID; - int encryptOID; /* key encryption algorithm OID */ + int encryptOID; /* key encryption algorithm OID */ - byte* singleCert; /* recipient cert, DER, not owner */ + byte* singleCert; /* recipient cert, DER, not owner */ word32 singleCertSz; /* size of recipient cert buffer, bytes */ - byte* issuer; /* issuer name of singleCert */ - word32 issuerSz; /* length of issuer name */ - byte issuerSn[MAX_SN_SZ]; /* singleCert's serial number */ - word32 issuerSnSz; /* length of serial number */ + byte issuerHash[SHA_SIZE]; /* hash of all alt Names */ + byte* issuer; /* issuer name of singleCert */ + word32 issuerSz; /* length of issuer name */ + byte issuerSn[MAX_SN_SZ]; /* singleCert's serial number */ + word32 issuerSnSz; /* length of serial number */ byte publicKey[512]; word32 publicKeySz; - byte* privateKey; /* private key, DER, not owner */ - word32 privateKeySz; /* size of private key buffer, bytes */ + byte* privateKey; /* private key, DER, not owner */ + word32 privateKeySz; /* size of private key buffer, bytes */ PKCS7Attrib* signedAttribs; word32 signedAttribsSz;