LCOV - code coverage report
Current view: top level - crypto - gmac.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 76 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: gmac.c,v 1.10 2017/05/02 11:44:32 mikeb Exp $ */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2010 Mike Belopuhov
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : /*
      20             :  * This code implements the Message Authentication part of the
      21             :  * Galois/Counter Mode (as being described in the RFC 4543) using
      22             :  * the AES cipher.  FIPS SP 800-38D describes the algorithm details.
      23             :  */
      24             : 
      25             : #include <sys/param.h>
      26             : #include <sys/systm.h>
      27             : 
      28             : #include <crypto/aes.h>
      29             : #include <crypto/gmac.h>
      30             : 
      31             : void    ghash_gfmul(uint32_t *, uint32_t *, uint32_t *);
      32             : void    ghash_update_mi(GHASH_CTX *, uint8_t *, size_t);
      33             : 
      34             : /* Allow overriding with optimized MD function */
      35             : void    (*ghash_update)(GHASH_CTX *, uint8_t *, size_t) = ghash_update_mi;
      36             : 
      37             : /* Computes a block multiplication in the GF(2^128) */
      38             : void
      39           0 : ghash_gfmul(uint32_t *X, uint32_t *Y, uint32_t *product)
      40             : {
      41             :         uint32_t        v[4];
      42             :         uint32_t        z[4] = { 0, 0, 0, 0};
      43           0 :         uint8_t         *x = (uint8_t *)X;
      44             :         uint32_t        mask;
      45             :         int             i;
      46             : 
      47           0 :         v[0] = betoh32(Y[0]);
      48           0 :         v[1] = betoh32(Y[1]);
      49           0 :         v[2] = betoh32(Y[2]);
      50           0 :         v[3] = betoh32(Y[3]);
      51             : 
      52           0 :         for (i = 0; i < GMAC_BLOCK_LEN * 8; i++) {
      53             :                 /* update Z */
      54           0 :                 mask = !!(x[i >> 3] & (1 << (~i & 7)));
      55           0 :                 mask = ~(mask - 1);
      56           0 :                 z[0] ^= v[0] & mask;
      57           0 :                 z[1] ^= v[1] & mask;
      58           0 :                 z[2] ^= v[2] & mask;
      59           0 :                 z[3] ^= v[3] & mask;
      60             : 
      61             :                 /* update V */
      62           0 :                 mask = ~((v[3] & 1) - 1);
      63           0 :                 v[3] = (v[2] << 31) | (v[3] >> 1);
      64           0 :                 v[2] = (v[1] << 31) | (v[2] >> 1);
      65           0 :                 v[1] = (v[0] << 31) | (v[1] >> 1);
      66           0 :                 v[0] = (v[0] >> 1) ^ (0xe1000000 & mask);
      67             :         }
      68             : 
      69           0 :         product[0] = htobe32(z[0]);
      70           0 :         product[1] = htobe32(z[1]);
      71           0 :         product[2] = htobe32(z[2]);
      72           0 :         product[3] = htobe32(z[3]);
      73           0 : }
      74             : 
      75             : void
      76           0 : ghash_update_mi(GHASH_CTX *ctx, uint8_t *X, size_t len)
      77             : {
      78           0 :         uint32_t        *x = (uint32_t *)X;
      79           0 :         uint32_t        *s = (uint32_t *)ctx->S;
      80           0 :         uint32_t        *y = (uint32_t *)ctx->Z;
      81             :         int             i;
      82             : 
      83           0 :         for (i = 0; i < len / GMAC_BLOCK_LEN; i++) {
      84           0 :                 s[0] = y[0] ^ x[0];
      85           0 :                 s[1] = y[1] ^ x[1];
      86           0 :                 s[2] = y[2] ^ x[2];
      87           0 :                 s[3] = y[3] ^ x[3];
      88             : 
      89           0 :                 ghash_gfmul((uint32_t *)ctx->S, (uint32_t *)ctx->H,
      90             :                     (uint32_t *)ctx->S);
      91             : 
      92             :                 y = s;
      93           0 :                 x += 4;
      94             :         }
      95             : 
      96           0 :         bcopy(ctx->S, ctx->Z, GMAC_BLOCK_LEN);
      97           0 : }
      98             : 
      99             : #define AESCTR_NONCESIZE        4
     100             : 
     101             : void
     102           0 : AES_GMAC_Init(void *xctx)
     103             : {
     104           0 :         AES_GMAC_CTX    *ctx = xctx;
     105             : 
     106           0 :         bzero(ctx->ghash.H, GMAC_BLOCK_LEN);
     107           0 :         bzero(ctx->ghash.S, GMAC_BLOCK_LEN);
     108           0 :         bzero(ctx->ghash.Z, GMAC_BLOCK_LEN);
     109           0 :         bzero(ctx->J, GMAC_BLOCK_LEN);
     110           0 : }
     111             : 
     112             : void
     113           0 : AES_GMAC_Setkey(void *xctx, const uint8_t *key, uint16_t klen)
     114             : {
     115           0 :         AES_GMAC_CTX    *ctx = xctx;
     116             : 
     117           0 :         AES_Setkey(&ctx->K, key, klen - AESCTR_NONCESIZE);
     118             :         /* copy out salt to the counter block */
     119           0 :         bcopy(key + klen - AESCTR_NONCESIZE, ctx->J, AESCTR_NONCESIZE);
     120             :         /* prepare a hash subkey */
     121           0 :         AES_Encrypt(&ctx->K, ctx->ghash.H, ctx->ghash.H);
     122           0 : }
     123             : 
     124             : void
     125           0 : AES_GMAC_Reinit(void *xctx, const uint8_t *iv, uint16_t ivlen)
     126             : {
     127           0 :         AES_GMAC_CTX    *ctx = xctx;
     128             : 
     129             :         /* copy out IV to the counter block */
     130           0 :         bcopy(iv, ctx->J + AESCTR_NONCESIZE, ivlen);
     131           0 : }
     132             : 
     133             : int
     134           0 : AES_GMAC_Update(void *xctx, const uint8_t *data, uint16_t len)
     135             : {
     136           0 :         AES_GMAC_CTX    *ctx = xctx;
     137           0 :         uint32_t        blk[4] = { 0, 0, 0, 0 };
     138             :         int             plen;
     139             : 
     140           0 :         if (len > 0) {
     141           0 :                 plen = len % GMAC_BLOCK_LEN;
     142           0 :                 if (len >= GMAC_BLOCK_LEN)
     143           0 :                         (*ghash_update)(&ctx->ghash, (uint8_t *)data,
     144           0 :                             len - plen);
     145           0 :                 if (plen) {
     146           0 :                         memcpy((uint8_t *)blk, (uint8_t *)data + (len - plen),
     147             :                             plen);
     148           0 :                         (*ghash_update)(&ctx->ghash, (uint8_t *)blk,
     149             :                             GMAC_BLOCK_LEN);
     150           0 :                 }
     151             :         }
     152           0 :         return (0);
     153           0 : }
     154             : 
     155             : void
     156           0 : AES_GMAC_Final(uint8_t digest[GMAC_DIGEST_LEN], void *xctx)
     157             : {
     158           0 :         AES_GMAC_CTX    *ctx = xctx;
     159           0 :         uint8_t         keystream[GMAC_BLOCK_LEN];
     160             :         int             i;
     161             : 
     162             :         /* do one round of GCTR */
     163           0 :         ctx->J[GMAC_BLOCK_LEN - 1] = 1;
     164           0 :         AES_Encrypt(&ctx->K, ctx->J, keystream);
     165           0 :         for (i = 0; i < GMAC_DIGEST_LEN; i++)
     166           0 :                 digest[i] = ctx->ghash.S[i] ^ keystream[i];
     167           0 :         explicit_bzero(keystream, sizeof(keystream));
     168           0 : }

Generated by: LCOV version 1.13