mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-08 11:00:50 +02:00
F-6427 - Reject RC2 cipher ops when no key is set
The RC2 encrypt and decrypt operations used the expanded key schedule without checking that a key had ever been configured. On a zeroed or otherwise unkeyed context the ECB ops ran over an all-zero schedule and returned success, and the CBC wrappers inherited the same behavior, so a caller who skipped wc_Rc2SetKey received ciphertext under an unintended key with no error signalled. Guard wc_Rc2EcbEncrypt and wc_Rc2EcbDecrypt on a zero keylen and return MISSING_KEY when no key has been set. The CBC wrappers call these and propagate the error. Mirrors the existing 3DES keySet guard. Add a regression test covering the unkeyed path for all four ops.
This commit is contained in:
@@ -228,6 +228,37 @@ int test_wc_Rc2CbcEncryptDecrypt(void)
|
||||
} /* END test_wc_Rc2CbcEncryptDecrypt */
|
||||
|
||||
|
||||
/*
|
||||
* Cipher operations must fail safely when no key has been configured.
|
||||
*/
|
||||
int test_wc_Rc2_MissingKey(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#ifdef WC_RC2
|
||||
Rc2 rc2;
|
||||
byte out[RC2_BLOCK_SIZE];
|
||||
byte in[RC2_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(out, 0, sizeof(out));
|
||||
XMEMSET(in, 0, sizeof(in));
|
||||
|
||||
/* Zeroed context, never keyed: every op must reject with MISSING_KEY
|
||||
* rather than ciphering under an all-zero key schedule. */
|
||||
XMEMSET(&rc2, 0, sizeof(rc2));
|
||||
|
||||
ExpectIntEQ(wc_Rc2EcbEncrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_Rc2EcbDecrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_Rc2CbcEncrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
ExpectIntEQ(wc_Rc2CbcDecrypt(&rc2, out, in, RC2_BLOCK_SIZE),
|
||||
WC_NO_ERR_TRACE(MISSING_KEY));
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_Rc2_MissingKey */
|
||||
|
||||
|
||||
#define MC_CIPHER_TEST_COUNT 100
|
||||
#define MC_RC2_MAX_DATA_SZ 1024
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ int test_wc_Rc2SetKey(void);
|
||||
int test_wc_Rc2SetIV(void);
|
||||
int test_wc_Rc2EcbEncryptDecrypt(void);
|
||||
int test_wc_Rc2CbcEncryptDecrypt(void);
|
||||
int test_wc_Rc2_MissingKey(void);
|
||||
int test_wc_Rc2Cbc_MonteCarlo(void);
|
||||
int test_wc_Rc2Free(void);
|
||||
|
||||
@@ -36,6 +37,7 @@ int test_wc_Rc2Free(void);
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2SetIV), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2EcbEncryptDecrypt), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2CbcEncryptDecrypt), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2_MissingKey), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2Cbc_MonteCarlo), \
|
||||
TEST_DECL_GROUP("rc2", test_wc_Rc2Free)
|
||||
|
||||
|
||||
+16
-8
@@ -171,6 +171,10 @@ int wc_Rc2EcbEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
r10 = (word16)((word16)in[1] << 8) | in[0]; /* R[0] */
|
||||
r32 = (word16)((word16)in[3] << 8) | in[2]; /* R[1] */
|
||||
r54 = (word16)((word16)in[5] << 8) | in[4]; /* R[2] */
|
||||
@@ -236,6 +240,10 @@ int wc_Rc2EcbDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
r0 = (word16)((word16)in[1] << 8) | in[0];
|
||||
r1 = (word16)((word16)in[3] << 8) | in[2];
|
||||
r2 = (word16)((word16)in[5] << 8) | in[4];
|
||||
@@ -285,14 +293,14 @@ int wc_Rc2CbcEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (sz == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sz % RC2_BLOCK_SIZE != 0) {
|
||||
return BAD_LENGTH_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
blocks = sz / RC2_BLOCK_SIZE;
|
||||
|
||||
while (blocks--) {
|
||||
@@ -320,14 +328,14 @@ int wc_Rc2CbcDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (sz == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sz % RC2_BLOCK_SIZE != 0) {
|
||||
return BAD_LENGTH_E;
|
||||
}
|
||||
|
||||
if (rc2->keylen == 0) {
|
||||
return MISSING_KEY;
|
||||
}
|
||||
|
||||
blocks = sz / RC2_BLOCK_SIZE;
|
||||
|
||||
while (blocks--) {
|
||||
|
||||
Reference in New Issue
Block a user