Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • master-updates
  • rename-data-symbols
  • x86_64-sha_ni-sha256
  • ecc-params-tweak
  • delete-old-aes
  • cmac-support
  • x86_64-sha_ni-sha1
  • gcm-ctr-opt
  • ctr-opt
  • skein
  • api-opaque-fix
  • curve448
  • hkdf-support
  • openssl-benchmark-update
  • merge-pss
  • rsa-crt-hardening
  • chacha96
  • fat-library
  • versioned-symbols
  • nettle_3.4_release_20171119
  • nettle_3.4rc2
  • nettle_3.4rc1
  • nettle_3.3_release_20161001
  • nettle_3.2_release_20160128
  • nettle_3.1.1_release_20150424
  • nettle_3.1_release_20150407
  • nettle_3.1rc3
  • nettle_3.1rc2
  • nettle_3.1rc1
  • nettle_3.0_release_20140607
  • nettle_2.7.1_release_20130528
  • nettle_2.7_release_20130424
  • nettle_2.6_release_20130116
  • nettle_2.5_release_20120707
  • converted-master-branch-to-git
  • nettle_2.4_release_20110903
  • nettle_2.3_release_20110902
  • nettle_2.2_release_20110711
  • nettle_2.1_release_20100725
40 results

camellia-set-encrypt-key.c

Blame
  • Forked from Nettle / nettle
    2704 commits behind the upstream repository.
    • Niels Möller's avatar
      c1552ab2
      * camellia-set-encrypt-key.c (camellia_setup128): Generate · c1552ab2
      Niels Möller authored
      unmodified subkeys according to the spec. Moved clever combination
      of subkeys to camellia_set_encrypt_key.
      (camellia_setup256): Likewise.
      (camellia_set_encrypt_key): Moved subkey post-processing code
      here, and reduce code duplication between 128-bit keys and larger
      keys.
      
      * camellia.c: Deleted file, split into several new files...
      * camellia-table.c (_camellia_table): New file with the constant
      sbox tables.
      * camellia-set-encrypt-key.c: New file.
      (camellia_setup128): Generate unmodified subkeys according to the
      spec. Moved clever combination of subkeys to camellia_set_encrypt_key.
      (camellia_setup256): Likewise.
      
      * camellia-set-decrypt-key.c: New file.
      (camellia_invert_key): Key inversion function.
      (camellia_set_decrypt_key): New key setup function.
      * camellia-internal.h: New file.
      * camellia-crypt.c (camellia_crypt): New file, new wrapper
      function passing the sbox table to _camellia_crypt.
      * camellia-crypt-internal.c (_camellia_crypt): New file, with main
      encrypt/decrypt function.
      * Makefile.in (nettle_SOURCES): Updated list of camellia source files.
      (DISTFILES): Added camellia-internal.h.
      
      Rev: nettle/ChangeLog:1.96
      Rev: nettle/Makefile.in:1.26
      Rev: nettle/camellia-crypt-internal.c:1.1
      Rev: nettle/camellia-crypt.c:1.1
      Rev: nettle/camellia-internal.h:1.1
      Rev: nettle/camellia-set-decrypt-key.c:1.1
      Rev: nettle/camellia-set-encrypt-key.c:1.1
      Rev: nettle/camellia-table.c:1.1
      Rev: nettle/camellia.c:1.5(DEAD)
      c1552ab2
      History
      * camellia-set-encrypt-key.c (camellia_setup128): Generate
      Niels Möller authored
      unmodified subkeys according to the spec. Moved clever combination
      of subkeys to camellia_set_encrypt_key.
      (camellia_setup256): Likewise.
      (camellia_set_encrypt_key): Moved subkey post-processing code
      here, and reduce code duplication between 128-bit keys and larger
      keys.
      
      * camellia.c: Deleted file, split into several new files...
      * camellia-table.c (_camellia_table): New file with the constant
      sbox tables.
      * camellia-set-encrypt-key.c: New file.
      (camellia_setup128): Generate unmodified subkeys according to the
      spec. Moved clever combination of subkeys to camellia_set_encrypt_key.
      (camellia_setup256): Likewise.
      
      * camellia-set-decrypt-key.c: New file.
      (camellia_invert_key): Key inversion function.
      (camellia_set_decrypt_key): New key setup function.
      * camellia-internal.h: New file.
      * camellia-crypt.c (camellia_crypt): New file, new wrapper
      function passing the sbox table to _camellia_crypt.
      * camellia-crypt-internal.c (_camellia_crypt): New file, with main
      encrypt/decrypt function.
      * Makefile.in (nettle_SOURCES): Updated list of camellia source files.
      (DISTFILES): Added camellia-internal.h.
      
      Rev: nettle/ChangeLog:1.96
      Rev: nettle/Makefile.in:1.26
      Rev: nettle/camellia-crypt-internal.c:1.1
      Rev: nettle/camellia-crypt.c:1.1
      Rev: nettle/camellia-internal.h:1.1
      Rev: nettle/camellia-set-decrypt-key.c:1.1
      Rev: nettle/camellia-set-encrypt-key.c:1.1
      Rev: nettle/camellia-table.c:1.1
      Rev: nettle/camellia.c:1.5(DEAD)
    camellia-set-encrypt-key.c 11.41 KiB
    /* camellia-set-encrypt-key.c
     *
     * Key setup for the camellia block cipher.
     */
    /*
     * Copyright (C) 2006,2007
     * NTT (Nippon Telegraph and Telephone Corporation).
     *
     * Copyright (C) 2010 Niels Mller
     *
     * This library is free software; you can redistribute it and/or
     * modify it under the terms of the GNU Lesser General Public
     * License as published by the Free Software Foundation; either
     * version 2.1 of the License, or (at your option) any later version.
     *
     * This library is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * Lesser General Public License for more details.
     *
     * You should have received a copy of the GNU Lesser General Public
     * License along with this library; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     */
    
    /*
     * Algorithm Specification 
     *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
     */
    
    /* Based on camellia.c ver 1.2.0, see
       http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
     */
    #if HAVE_CONFIG_H
    # include "config.h"
    #endif
    
    #include <assert.h>
    
    #include "camellia-internal.h"
    
    #include "macros.h"
    
    /* key constants */
    
    #define SIGMA1 0xA09E667F3BCC908BULL
    #define SIGMA2 0xB67AE8584CAA73B2ULL
    #define SIGMA3 0xC6EF372FE94F82BEULL
    #define SIGMA4 0x54FF53A5F1D36F1CULL
    #define SIGMA5 0x10E527FADE682D1DULL
    #define SIGMA6 0xB05688C2B3E6C1FDULL
    
    #define CAMELLIA_SP1110(INDEX) (_nettle_camellia_table.sp1110[(int)(INDEX)])
    #define CAMELLIA_SP0222(INDEX) (_nettle_camellia_table.sp0222[(int)(INDEX)])
    #define CAMELLIA_SP3033(INDEX) (_nettle_camellia_table.sp3033[(int)(INDEX)])
    #define CAMELLIA_SP4404(INDEX) (_nettle_camellia_table.sp4404[(int)(INDEX)])
    
    #define CAMELLIA_F(x, k, y) do {		\
        uint32_t __yl, __yr;			\
        uint64_t __i = (x) ^ (k);			\
        __yl					\
          = CAMELLIA_SP1110( __i & 0xff)		\
          ^ CAMELLIA_SP0222((__i >> 24) & 0xff)	\
          ^ CAMELLIA_SP3033((__i >> 16) & 0xff)	\
          ^ CAMELLIA_SP4404((__i >> 8) & 0xff);	\
        __yr					\
          = CAMELLIA_SP1110( __i >> 56)		\
          ^ CAMELLIA_SP0222((__i >> 48) & 0xff)	\
          ^ CAMELLIA_SP3033((__i >> 40) & 0xff)	\
          ^ CAMELLIA_SP4404((__i >> 32) & 0xff);	\
        __yl ^= __yr;				\
        __yr = ROL32(24, __yr);			\
        __yr ^= __yl;				\
        (y) = ((uint64_t) __yl << 32) | __yr;	\
      } while (0)
    
    #define CAMELLIA_F_HALF_INV(x) do {		\
        uint32_t __t, __w;				\
        __t = (x) >> 32;				\
        __w = __t ^(x);				\
        __w = ROL32(8, __w);			\
        (x) = ((uint64_t) __w << 32) | (__t ^ __w);	\
      } while (0)
    
    
    static void
    camellia_setup128(uint64_t *subkey, const uint64_t *key)
    {
        uint64_t k0, k1, w;
    
        /**
         *  k == k0 || k1 (|| is concatenation)
         */
        k0 = key[0];
        k1 = key[1];
    
        /**
         * generate KL dependent subkeys
         */
        subkey[0] = k0; subkey[1] = k1;
        ROL128(15, k0, k1);
        subkey[4] = k0; subkey[5] = k1;
        ROL128(30, k0, k1);
        subkey[10] = k0; subkey[11] = k1;
        ROL128(15, k0, k1);
        subkey[13] = k1;
        ROL128(17, k0, k1);
        subkey[16] = k0; subkey[17] = k1;
        ROL128(17, k0, k1);
        subkey[18] = k0; subkey[19] = k1;
        ROL128(17, k0, k1);
        subkey[22] = k0; subkey[23] = k1;
    
        /* generate KA. D1 is k0, d2 is k1. */
        /* FIXME: Make notation match the spec better. */
        /* For the 128-bit case, KR = 0, the construvtion of KA reduces to:
    
           D1 = KL >> 64;
           W = KL & MASK64;
           D2 = F(D1, Sigma1);
           W = D2 ^ W
           D1 = F(W, Sigma2)
           D2 = D2 ^ F(D1, Sigma3);
           D1 = D1 ^ F(D2, Sigma4);
           KA = (D1 << 64) | D2;
        */
        k0 = subkey[0]; w = subkey[1];
        CAMELLIA_F(k0, SIGMA1, k1);
        w ^= k1;
        CAMELLIA_F(w, SIGMA2, k0);
        CAMELLIA_F(k0, SIGMA3, w);
        k1 ^= w;
        CAMELLIA_F(k1, SIGMA4, w);
        k0 ^= w;
    
        /* generate KA dependent subkeys */
        subkey[2] = k0; subkey[3] = k1;
        ROL128(15, k0, k1);
        subkey[6] = k0; subkey[7] = k1;
        ROL128(15, k0, k1);
        subkey[8] = k0; subkey[9] = k1;
        ROL128(15, k0, k1);
        subkey[12] = k0;
        ROL128(15, k0, k1);
        subkey[14] = k0; subkey[15] = k1;
        ROL128(34, k0, k1);
        subkey[20] = k0; subkey[21] = k1;
        ROL128(17, k0, k1);
        subkey[24] = k0; subkey[25] = k1;
    
        return;
    }
    
    static void
    camellia_setup256(uint64_t *subkey, const uint64_t *key)
    {
        uint64_t k0, k1, k2, k3;
        uint64_t w;
    
        /**
         *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
         *  (|| is concatenation)
         */
    
        k0  = key[0];
        k1  = key[1];
        k2  = key[2];
        k3  = key[3];
    
        /* generate KL dependent subkeys */
        subkey[0] = k0; subkey[1] = k1;
        ROL128(45, k0, k1);
        subkey[12] = k0; subkey[13] = k1;
        ROL128(15, k0, k1);
        subkey[16] = k0; subkey[17] = k1;
        ROL128(17, k0, k1);
        subkey[22] = k0; subkey[23] = k1;
        ROL128(34, k0, k1);
        subkey[30] = k0; subkey[31] = k1;
    
        /* generate KR dependent subkeys */
        ROL128(15, k2, k3);
        subkey[4] = k2; subkey[5] = k3;
        ROL128(15, k2, k3);
        subkey[8] = k2; subkey[9] = k3;
        ROL128(30, k2, k3);
        subkey[18] = k2; subkey[19] = k3;
        ROL128(34, k2, k3);
        subkey[26] = k2; subkey[27] = k3;
        ROL128(34, k2, k3);
    
        /* generate KA */
        /* The construction of KA is done as
    
           D1 = (KL ^ KR) >> 64
           D2 = (KL ^ KR) & MASK64
           W = F(D1, SIGMA1)
           D2 = D2 ^ W
           D1 = F(D2, SIGMA2) ^ (KR >> 64)
           D2 = F(D1, SIGMA3) ^ W ^ (KR & MASK64)
           D1 = D1 ^ F(W, SIGMA2)
           D2 = D2 ^ F(D1, SIGMA3)
           D1 = D1 ^ F(D2, SIGMA4)
        */
    
        k0 = subkey[0] ^ k2;
        k1 = subkey[1] ^ k3;
    
        CAMELLIA_F(k0, SIGMA1, w);
        k1 ^= w;
    
        CAMELLIA_F(k1, SIGMA2, k0);
        k0 ^= k2;
    
        CAMELLIA_F(k0, SIGMA3, k1);
        k1 ^= w ^ k3;
    
        CAMELLIA_F(k1, SIGMA4, w);
        k0 ^= w;
    
        /* generate KB */
        k2 ^= k0; k3 ^= k1;
        CAMELLIA_F(k2, SIGMA5, w);
        k3 ^= w;
        CAMELLIA_F(k3, SIGMA6, w);
        k2 ^= w;
    
        /* generate KA dependent subkeys */
        ROL128(15, k0, k1);
        subkey[6] = k0; subkey[7] = k1;
        ROL128(30, k0, k1);
        subkey[14] = k0; subkey[15] = k1;
        ROL128(32, k0, k1);
        subkey[24] = k0; subkey[25] = k1;
        ROL128(17, k0, k1);
        subkey[28] = k0; subkey[29] = k1;
    
        /* generate KB dependent subkeys */
        subkey[2] = k2; subkey[3] = k3;
        ROL128(30, k2, k3);
        subkey[10] = k2; subkey[11] = k3;
        ROL128(30, k2, k3);
        subkey[20] = k2; subkey[21] = k3;
        ROL128(51, k2, k3);
        subkey[32] = k2; subkey[33] = k3;
    
        return;
    }
    
    void
    camellia_set_encrypt_key(struct camellia_ctx *ctx,
    			 unsigned length, const uint8_t *key)
    {
      uint64_t k[4];
    
      /* Subkeys according to the spec, 26 for short keys and 34 for large
         keys */
      uint64_t subkey[34];
      uint64_t kw4;
      
      uint32_t dw, tl, tr;
      unsigned i;
    
      k[0] = READ_UINT64(key);
      k[1] = READ_UINT64(key +  8);
      
      if (length == 16)
        {
          ctx->nkeys = 26;
          camellia_setup128(subkey, k);
        }
      else
        {
          ctx->nkeys = 34;
          k[2] = READ_UINT64(key + 16);
    
          if (length == 24)
    	k[3] = ~k[2];
          else
    	{
    	  assert (length == 32);
    	  k[3] = READ_UINT64(key + 24);
    	}
          camellia_setup256(subkey, k);
        }
    
      /* absorb kw2 to other subkeys */
      subkey[3] ^= subkey[1];
      subkey[5] ^= subkey[1];
      subkey[7] ^= subkey[1];
      /* FIXME: gcc for x86_32 is smart enough to fetch the 32 low bits
         and xor the result into the 32 high bits, but it still generates
         worse code than for explicit 32-bit operations. */
      subkey[1] ^= (subkey[1] & ~subkey[9]) << 32;
      dw = (subkey[1] & subkey[9]) >> 32; subkey[1] ^= ROL32(1, dw); 
    
      subkey[11] ^= subkey[1];
      subkey[13] ^= subkey[1];
      subkey[15] ^= subkey[1];
      subkey[1] ^= (subkey[1] & ~subkey[17]) << 32;
      dw = (subkey[1] & subkey[17]) >> 32; subkey[1] ^= ROL32(1, dw); 
    
      subkey[19] ^= subkey[1];
      subkey[21] ^= subkey[1];
      subkey[23] ^= subkey[1];
      if (ctx->nkeys < 32)
        {
          subkey[24] ^= subkey[1];
        }
      else
        {
          subkey[1] ^= (subkey[1] & ~subkey[25]) << 32;
          dw = (subkey[1] & subkey[25]) >> 32; subkey[1] ^= ROL32(1, dw); 
    
          subkey[27] ^= subkey[1];
          subkey[29] ^= subkey[1];
          subkey[31] ^= subkey[1];
          subkey[32] ^= subkey[1];
        }
        
      /* absorb kw4 to other subkeys */  
      kw4 = subkey[ctx->nkeys - 1];
      
      if (ctx->nkeys >= 32)
        {
          subkey[30] ^= kw4;
          subkey[28] ^= kw4;
          subkey[26] ^= kw4;
          kw4 ^= (kw4 & ~subkey[24]) << 32;
          dw = (kw4 & subkey[24]) >> 32; kw4 ^= ROL32(1, dw);      
        }
    
      subkey[22] ^= kw4;
      subkey[20] ^= kw4;
      subkey[18] ^= kw4;
      kw4 ^= (kw4 & ~subkey[16]) << 32;
      dw = (kw4 & subkey[16]) >> 32; kw4 ^= ROL32(1, dw);
    
      subkey[14] ^= kw4;
      subkey[12] ^= kw4;
      subkey[10] ^= kw4;
      kw4 ^= (kw4 & ~subkey[8]) << 32;
      dw = (kw4 & subkey[8]) >> 32; kw4 ^= ROL32(1, dw);
    
      subkey[6] ^= kw4;
      subkey[4] ^= kw4;
      subkey[2] ^= kw4;
      subkey[0] ^= kw4;
    
      /* key XOR is end of F-function */
      ctx->keys[0] = subkey[0] ^subkey[2];
        
      ctx->keys[2] = subkey[3];
      ctx->keys[3] = subkey[2] ^ subkey[4];
      ctx->keys[4] = subkey[3] ^ subkey[5];
      ctx->keys[5] = subkey[4] ^ subkey[6];
      ctx->keys[6] = subkey[5] ^ subkey[7];
    
      tl = (subkey[10] >> 32) ^ (subkey[10] & ~subkey[8]);
      dw = tl & (subkey[8] >> 32);
      tr = subkey[10] ^ROL32(1, dw);
      ctx->keys[7] = subkey[6] ^ ( ((uint64_t) tl << 32) | tr);
    
      ctx->keys[8] = subkey[8];
      ctx->keys[9] = subkey[9];
    
      tl = (subkey[7] >> 32) ^ (subkey[7] & ~subkey[9]);
      dw = tl & (subkey[9] >> 32);
      tr = subkey[7] ^ ROL32(1, dw);
      ctx->keys[10] = subkey[11] ^ ( ((uint64_t) tl << 32) | tr);
    
      ctx->keys[11] = subkey[10] ^ subkey[12];
      ctx->keys[12] = subkey[11] ^ subkey[13];
      ctx->keys[13] = subkey[12] ^ subkey[14];
      ctx->keys[14] = subkey[13] ^ subkey[15];
    
      tl = (subkey[18] >> 32) ^ (subkey[18] & ~subkey[16]);
      dw = tl & (subkey[16] >> 32);
      tr = subkey[18] ^ ROL32(1, dw);
      ctx->keys[15] = subkey[14] ^ ( ((uint64_t) tl << 32) | tr);
    
      ctx->keys[16] = subkey[16];
      ctx->keys[17] = subkey[17];
    
      tl = (subkey[15] >> 32) ^ (subkey[15] & ~subkey[17]);
      dw = tl & (subkey[17] >> 32);
      tr = subkey[15] ^ ROL32(1, dw);
      ctx->keys[18] = subkey[19] ^ ( ((uint64_t) tl << 32) | tr);
    
      ctx->keys[19] = subkey[18] ^ subkey[20];
      ctx->keys[20] = subkey[19] ^ subkey[21];
      ctx->keys[21] = subkey[20] ^ subkey[22];
      ctx->keys[22] = subkey[21] ^ subkey[23];
    
      if (ctx->nkeys < 32)
        {
          ctx->keys[23] = subkey[22];
          ctx->keys[24] = subkey[24] ^ subkey[23];
    	  
        }
      else
        {
          tl = (subkey[26] >> 32) ^ (subkey[26] & ~subkey[24]);
          dw = tl & (subkey[24] >> 32);
          tr = subkey[26] ^ ROL32(1, dw);
          ctx->keys[23] = subkey[22] ^ ( ((uint64_t) tl << 32) | tr);
    
          ctx->keys[24] = subkey[24];
          ctx->keys[25] = subkey[25];
    
          tl = (subkey[23] >> 32) ^ (subkey[23] & ~subkey[25]);
          dw = tl & (subkey[25] >> 32);
          tr = subkey[23] ^ ROL32(1, dw);
          ctx->keys[26] = subkey[27] ^ ( ((uint64_t) tl << 32) | tr);
    
          ctx->keys[27] = subkey[26] ^ subkey[28];
          ctx->keys[28] = subkey[27] ^ subkey[29];
          ctx->keys[29] = subkey[28] ^ subkey[30];
          ctx->keys[30] = subkey[29] ^ subkey[31];
    
          ctx->keys[31] = subkey[30];
          ctx->keys[32] = subkey[32] ^ subkey[31];
    	  
        }
      for (i = 0; i < ctx->nkeys - 2; i += 8)
        {
    
          /* apply the inverse of the last half of F-function */
          CAMELLIA_F_HALF_INV(ctx->keys[i+2]);
          CAMELLIA_F_HALF_INV(ctx->keys[i+3]);
          CAMELLIA_F_HALF_INV(ctx->keys[i+4]);
          CAMELLIA_F_HALF_INV(ctx->keys[i+5]);
          CAMELLIA_F_HALF_INV(ctx->keys[i+6]);
          CAMELLIA_F_HALF_INV(ctx->keys[i+7]);
        }
    }