linux/include/crypto/internal/des.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * DES & Triple DES EDE key verification helpers
   4 */
   5
   6#ifndef __CRYPTO_INTERNAL_DES_H
   7#define __CRYPTO_INTERNAL_DES_H
   8
   9#include <linux/crypto.h>
  10#include <linux/fips.h>
  11#include <crypto/des.h>
  12#include <crypto/aead.h>
  13#include <crypto/skcipher.h>
  14
  15/**
  16 * crypto_des_verify_key - Check whether a DES key is weak
  17 * @tfm: the crypto algo
  18 * @key: the key buffer
  19 *
  20 * Returns -EINVAL if the key is weak and the crypto TFM does not permit weak
  21 * keys. Otherwise, 0 is returned.
  22 *
  23 * It is the job of the caller to ensure that the size of the key equals
  24 * DES_KEY_SIZE.
  25 */
  26static inline int crypto_des_verify_key(struct crypto_tfm *tfm, const u8 *key)
  27{
  28        struct des_ctx tmp;
  29        int err;
  30
  31        err = des_expand_key(&tmp, key, DES_KEY_SIZE);
  32        if (err == -ENOKEY) {
  33                if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS)
  34                        err = -EINVAL;
  35                else
  36                        err = 0;
  37        }
  38
  39        if (err)
  40                crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY);
  41
  42        memzero_explicit(&tmp, sizeof(tmp));
  43        return err;
  44}
  45
  46/*
  47 * RFC2451:
  48 *
  49 *   For DES-EDE3, there is no known need to reject weak or
  50 *   complementation keys.  Any weakness is obviated by the use of
  51 *   multiple keys.
  52 *
  53 *   However, if the first two or last two independent 64-bit keys are
  54 *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
  55 *   same as DES.  Implementers MUST reject keys that exhibit this
  56 *   property.
  57 *
  58 */
  59static inline int des3_ede_verify_key(const u8 *key, unsigned int key_len,
  60                                      bool check_weak)
  61{
  62        int ret = fips_enabled ? -EINVAL : -ENOKEY;
  63        u32 K[6];
  64
  65        memcpy(K, key, DES3_EDE_KEY_SIZE);
  66
  67        if ((!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
  68             !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
  69            (fips_enabled || check_weak))
  70                goto bad;
  71
  72        if ((!((K[0] ^ K[4]) | (K[1] ^ K[5]))) && fips_enabled)
  73                goto bad;
  74
  75        ret = 0;
  76bad:
  77        memzero_explicit(K, DES3_EDE_KEY_SIZE);
  78
  79        return ret;
  80}
  81
  82/**
  83 * crypto_des3_ede_verify_key - Check whether a DES3-EDE key is weak
  84 * @tfm: the crypto algo
  85 * @key: the key buffer
  86 *
  87 * Returns -EINVAL if the key is weak and the crypto TFM does not permit weak
  88 * keys or when running in FIPS mode. Otherwise, 0 is returned. Note that some
  89 * keys are rejected in FIPS mode even if weak keys are permitted by the TFM
  90 * flags.
  91 *
  92 * It is the job of the caller to ensure that the size of the key equals
  93 * DES3_EDE_KEY_SIZE.
  94 */
  95static inline int crypto_des3_ede_verify_key(struct crypto_tfm *tfm,
  96                                             const u8 *key)
  97{
  98        int err;
  99
 100        err = des3_ede_verify_key(key, DES3_EDE_KEY_SIZE,
 101                                  crypto_tfm_get_flags(tfm) &
 102                                  CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
 103        if (err)
 104                crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY);
 105        return err;
 106}
 107
 108static inline int verify_skcipher_des_key(struct crypto_skcipher *tfm,
 109                                          const u8 *key)
 110{
 111        return crypto_des_verify_key(crypto_skcipher_tfm(tfm), key);
 112}
 113
 114static inline int verify_skcipher_des3_key(struct crypto_skcipher *tfm,
 115                                           const u8 *key)
 116{
 117        return crypto_des3_ede_verify_key(crypto_skcipher_tfm(tfm), key);
 118}
 119
 120static inline int verify_ablkcipher_des_key(struct crypto_ablkcipher *tfm,
 121                                            const u8 *key)
 122{
 123        return crypto_des_verify_key(crypto_ablkcipher_tfm(tfm), key);
 124}
 125
 126static inline int verify_ablkcipher_des3_key(struct crypto_ablkcipher *tfm,
 127                                             const u8 *key)
 128{
 129        return crypto_des3_ede_verify_key(crypto_ablkcipher_tfm(tfm), key);
 130}
 131
 132static inline int verify_aead_des_key(struct crypto_aead *tfm, const u8 *key,
 133                                      int keylen)
 134{
 135        if (keylen != DES_KEY_SIZE) {
 136                crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
 137                return -EINVAL;
 138        }
 139        return crypto_des_verify_key(crypto_aead_tfm(tfm), key);
 140}
 141
 142static inline int verify_aead_des3_key(struct crypto_aead *tfm, const u8 *key,
 143                                       int keylen)
 144{
 145        if (keylen != DES3_EDE_KEY_SIZE) {
 146                crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
 147                return -EINVAL;
 148        }
 149        return crypto_des3_ede_verify_key(crypto_aead_tfm(tfm), key);
 150}
 151
 152#endif /* __CRYPTO_INTERNAL_DES_H */
 153