Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/crypto/krb5/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  rfc6803_camellia.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/* rfc6803 Camellia Encryption for Kerberos 5
 *
 * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/slab.h>
#include "internal.h"

/*
 * Calculate the key derivation function KDF-FEEDBACK_CMAC(key, constant)
 *
 * n = ceiling(k / 128)
 * K(0) = zeros
 * K(i) = CMAC(key, K(i-1) | i | constant | 0x00 | k)
 * DR(key, constant) = k-truncate(K(1) | K(2) | ... | K(n))
 * KDF-FEEDBACK-CMAC(key, constant) = random-to-key(DR(key, constant))
 *
 * [rfc6803 sec 3]
 */

static int rfc6803_calc_KDF_FEEDBACK_CMAC(const struct krb5_enctype *krb5,
       const struct krb5_buffer *key,
       const struct krb5_buffer *constant,
       struct krb5_buffer *result,
       gfp_t gfp)
{
 struct crypto_shash *shash;
 struct krb5_buffer K, data;
 struct shash_desc *desc;
 __be32 tmp;
 size_t bsize, offset, seg;
 void *buffer;
 u32 i = 0, k = result->len * 8;
 u8 *p;
 int ret = -ENOMEM;

 shash = crypto_alloc_shash(krb5->cksum_name, 0, 0);
 if (IS_ERR(shash))
  return (PTR_ERR(shash) == -ENOENT) ? -ENOPKG : PTR_ERR(shash);
 ret = crypto_shash_setkey(shash, key->data, key->len);
 if (ret < 0)
  goto error_shash;

 ret = -ENOMEM;
 K.len = crypto_shash_digestsize(shash);
 data.len = K.len + 4 + constant->len + 1 + 4;
 bsize = krb5_shash_size(shash) +
  krb5_digest_size(shash) +
  crypto_roundup(K.len) +
  crypto_roundup(data.len);
 buffer = kzalloc(bsize, GFP_NOFS);
 if (!buffer)
  goto error_shash;

 desc = buffer;
 desc->tfm = shash;

 K.data = buffer +
  krb5_shash_size(shash) +
  krb5_digest_size(shash);
 data.data = buffer +
  krb5_shash_size(shash) +
  krb5_digest_size(shash) +
  crypto_roundup(K.len);

 p = data.data + K.len + 4;
 memcpy(p, constant->data, constant->len);
 p += constant->len;
 *p++ = 0x00;
 tmp = htonl(k);
 memcpy(p, &tmp, 4);
 p += 4;

 ret = -EINVAL;
 if (WARN_ON(p - (u8 *)data.data != data.len))
  goto error;

 offset = 0;
 do {
  i++;
  p = data.data;
  memcpy(p, K.data, K.len);
  p += K.len;
  *(__be32 *)p = htonl(i);

  ret = crypto_shash_init(desc);
  if (ret < 0)
   goto error;
  ret = crypto_shash_finup(desc, data.data, data.len, K.data);
  if (ret < 0)
   goto error;

  seg = min_t(size_t, result->len - offset, K.len);
  memcpy(result->data + offset, K.data, seg);
  offset += seg;
 } while (offset < result->len);

error:
 kfree_sensitive(buffer);
error_shash:
 crypto_free_shash(shash);
 return ret;
}

/*
 * Calculate the pseudo-random function, PRF().
 *
 * Kp = KDF-FEEDBACK-CMAC(protocol-key, "prf")
 * PRF = CMAC(Kp, octet-string)
 *      [rfc6803 sec 6]
 */

static int rfc6803_calc_PRF(const struct krb5_enctype *krb5,
       const struct krb5_buffer *protocol_key,
       const struct krb5_buffer *octet_string,
       struct krb5_buffer *result,
       gfp_t gfp)
{
 static const struct krb5_buffer prfconstant = { 3, "prf" };
 struct crypto_shash *shash;
 struct krb5_buffer Kp;
 struct shash_desc *desc;
 size_t bsize;
 void *buffer;
 int ret;

 Kp.len = krb5->prf_len;

 shash = crypto_alloc_shash(krb5->cksum_name, 0, 0);
 if (IS_ERR(shash))
  return (PTR_ERR(shash) == -ENOENT) ? -ENOPKG : PTR_ERR(shash);

 ret = -EINVAL;
 if (result->len != crypto_shash_digestsize(shash))
  goto out_shash;

 ret = -ENOMEM;
 bsize = krb5_shash_size(shash) +
  krb5_digest_size(shash) +
  crypto_roundup(Kp.len);
 buffer = kzalloc(bsize, GFP_NOFS);
 if (!buffer)
  goto out_shash;

 Kp.data = buffer +
  krb5_shash_size(shash) +
  krb5_digest_size(shash);

 ret = rfc6803_calc_KDF_FEEDBACK_CMAC(krb5, protocol_key, &prfconstant,
          &Kp, gfp);
 if (ret < 0)
  goto out;

 ret = crypto_shash_setkey(shash, Kp.data, Kp.len);
 if (ret < 0)
  goto out;

 desc = buffer;
 desc->tfm = shash;
 ret = crypto_shash_init(desc);
 if (ret < 0)
  goto out;

 ret = crypto_shash_finup(desc, octet_string->data, octet_string->len, result->data);
 if (ret < 0)
  goto out;

out:
 kfree_sensitive(buffer);
out_shash:
 crypto_free_shash(shash);
 return ret;
}


static const struct krb5_crypto_profile rfc6803_crypto_profile = {
 .calc_PRF  = rfc6803_calc_PRF,
 .calc_Kc  = rfc6803_calc_KDF_FEEDBACK_CMAC,
 .calc_Ke  = rfc6803_calc_KDF_FEEDBACK_CMAC,
 .calc_Ki  = rfc6803_calc_KDF_FEEDBACK_CMAC,
 .derive_encrypt_keys = authenc_derive_encrypt_keys,
 .load_encrypt_keys = authenc_load_encrypt_keys,
 .derive_checksum_key = rfc3961_derive_checksum_key,
 .load_checksum_key = rfc3961_load_checksum_key,
 .encrypt  = krb5_aead_encrypt,
 .decrypt  = krb5_aead_decrypt,
 .get_mic  = rfc3961_get_mic,
 .verify_mic  = rfc3961_verify_mic,
};

const struct krb5_enctype krb5_camellia128_cts_cmac = {
 .etype  = KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC,
 .ctype  = KRB5_CKSUMTYPE_CMAC_CAMELLIA128,
 .name  = "camellia128-cts-cmac",
 .encrypt_name = "krb5enc(cmac(camellia),cts(cbc(camellia)))",
 .cksum_name = "cmac(camellia)",
 .hash_name = NULL,
 .derivation_enc = "cts(cbc(camellia))",
 .key_bytes = 16,
 .key_len = 16,
 .Kc_len  = 16,
 .Ke_len  = 16,
 .Ki_len  = 16,
 .block_len = 16,
 .conf_len = 16,
 .cksum_len = 16,
 .hash_len = 16,
 .prf_len = 16,
 .keyed_cksum = true,
 .random_to_key = NULL, /* Identity */
 .profile = &rfc6803_crypto_profile,
};

const struct krb5_enctype krb5_camellia256_cts_cmac = {
 .etype  = KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC,
 .ctype  = KRB5_CKSUMTYPE_CMAC_CAMELLIA256,
 .name  = "camellia256-cts-cmac",
 .encrypt_name = "krb5enc(cmac(camellia),cts(cbc(camellia)))",
 .cksum_name = "cmac(camellia)",
 .hash_name = NULL,
 .derivation_enc = "cts(cbc(camellia))",
 .key_bytes = 32,
 .key_len = 32,
 .Kc_len  = 32,
 .Ke_len  = 32,
 .Ki_len  = 32,
 .block_len = 16,
 .conf_len = 16,
 .cksum_len = 16,
 .hash_len = 16,
 .prf_len = 16,
 .keyed_cksum = true,
 .random_to_key = NULL, /* Identity */
 .profile = &rfc6803_crypto_profile,
};

Messung V0.5
C=94 H=94 G=93

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.