aboutsummaryrefslogtreecommitdiff
path: root/crypto/openssl/crypto/des/set_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssl/crypto/des/set_key.c')
-rw-r--r--crypto/openssl/crypto/des/set_key.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/crypto/openssl/crypto/des/set_key.c b/crypto/openssl/crypto/des/set_key.c
index cbcb616cb2ad..adcfb7f12451 100644
--- a/crypto/openssl/crypto/des/set_key.c
+++ b/crypto/openssl/crypto/des/set_key.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -15,12 +15,18 @@
* 1.1 added norm_expand_bits
* 1.0 First working version
*/
+
+/*
+ * DES low level APIs are deprecated for public use, but still ok for internal
+ * use.
+ */
+#include "internal/deprecated.h"
+
#include <openssl/crypto.h>
+#include "internal/constant_time.h"
+#include "internal/nelem.h"
#include "des_local.h"
-/* defaults to false */
-OPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key, 0)
-
static const unsigned char odd_parity[256] = {
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
@@ -58,15 +64,23 @@ void DES_set_odd_parity(DES_cblock *key)
(*key)[i] = odd_parity[(*key)[i]];
}
+/*
+ * Check that a key has the correct parity.
+ * Return 1 if parity is okay and 0 if not.
+ */
int DES_check_key_parity(const_DES_cblock *key)
{
unsigned int i;
+ unsigned char res = 0377, b;
for (i = 0; i < DES_KEY_SZ; i++) {
- if ((*key)[i] != odd_parity[(*key)[i]])
- return 0;
+ b = (*key)[i];
+ b ^= b >> 4;
+ b ^= b >> 2;
+ b ^= b >> 1;
+ res &= constant_time_eq_8(b & 1, 1);
}
- return 1;
+ return (int)(res & 1);
}
/*-
@@ -77,8 +91,7 @@ int DES_check_key_parity(const_DES_cblock *key)
* %I John Wiley & Sons
* %D 1984
*/
-#define NUM_WEAK_KEY 16
-static const DES_cblock weak_keys[NUM_WEAK_KEY] = {
+static const DES_cblock weak_keys[] = {
/* weak keys */
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
{0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE},
@@ -99,14 +112,20 @@ static const DES_cblock weak_keys[NUM_WEAK_KEY] = {
{0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1}
};
+/*
+ * Check for weak keys.
+ * Return 1 if the key is weak and 0 otherwise.
+ */
int DES_is_weak_key(const_DES_cblock *key)
{
- int i;
+ unsigned int i, res = 0;
+ int j;
- for (i = 0; i < NUM_WEAK_KEY; i++)
- if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0)
- return 1;
- return 0;
+ for (i = 0; i < OSSL_NELEM(weak_keys); i++) {
+ j = CRYPTO_memcmp(weak_keys[i], key, sizeof(DES_cblock));
+ res |= constant_time_is_zero((unsigned int)j);
+ }
+ return (int)(res & 1);
}
/*-
@@ -275,14 +294,17 @@ static const DES_LONG des_skb[8][64] = {
}
};
+/* Return values as DES_set_key_checked() but always set the key */
int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
{
- if (DES_check_key) {
- return DES_set_key_checked(key, schedule);
- } else {
- DES_set_key_unchecked(key, schedule);
- return 0;
- }
+ int ret = 0;
+
+ if (!DES_check_key_parity(key))
+ ret = -1;
+ if (DES_is_weak_key(key))
+ ret = -2;
+ DES_set_key_unchecked(key, schedule);
+ return ret;
}
/*-