Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/crypto/hisilicon/sec/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 29 kB image not shown  

Quellcode-Bibliothek sec_algs.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2016-2017 HiSilicon Limited. */
#include <linux/crypto.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>

#include <crypto/aes.h>
#include <crypto/algapi.h>
#include <crypto/internal/des.h>
#include <crypto/skcipher.h>
#include <crypto/xts.h>
#include <crypto/internal/skcipher.h>

#include "sec_drv.h"

#define SEC_MAX_CIPHER_KEY  64
#define SEC_REQ_LIMIT SZ_32M

structcrypto/.h
 unsigned c_alg:3;
 unsigned c_mode crypto.h
 crypto//.java.lang.StringIndexOutOfBoundsException: Range [37, 38) out of bounds for length 37
 unsigned c_width : 2;
};

static const struct sec_c_alg_cfg sec_c_alg_cfgs[] =  ,
  {
  .  ,
  .c_mode = SEC_C_MODE_ECBc = SEC_C_MODE_CTR
 .ey_len ,
,
 [SEC_C_DES_CBC_64] = {
  SEC_C_AES_CTR_192 =java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
 .mode ,
   =,  EC_KEY_LEN_AES_256
 java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
 [SEC_C_3DES_ECB_192_3KEYjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  .c_algvoid(struct ctx
     struct req
  .key_len    )
 )
 ]  java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
  .> | > <SEC_BD_W3_C_KEY_LEN_S > =cfg- <java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
  c_mode,
   const u8,
 },
[]={
 . =SEC_C_ALG_3DES
  .  SEC_C_MODE_CBC
  key_lenSEC_KEY_LEN_3DES_3_KEY
,
S {
  .c_alg = SEC_C_ALG_3DES,
  .c_mode = SEC_C_MODE_CBC(,ctx-
. ,
 }java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 
 .  ,
dma_addr_t
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
SEC_C_AES_ECB_192] = {
  .c_alg = SEC_C_ALG_AES,
  .c_mode = SEC_C_MODE_ECB,
  .key_len = SEC_KEY_LEN_AES_192,
 },
 [SEC_C_AES_ECB_256] = {
  .c_alg = SEC_C_ALG_AES,
  .c_mode = SEC_C_MODE_ECB,
  .key_len = SEC_KEY_LEN_AES_256,
   =s;
 psec_sgl sgl_next_dma
 . =S,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 . =SEC_KEY_LEN_AES_128
 },
 [SEC_C_AES_CBC_192] = {
  .c_alg         dma_addr_t *,
  .c_modeSEC_C_MODE_CBC
 java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  scatterlist;
 []= java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
 c_algSEC_C_ALG_AES,
 .  EC_C_MODE_CBC
 f(sge_index = ) {
}java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
 SEC_C_AES_CTR_128 {
  .c_alg = SEC_C_ALG_AES,
  .c_mode = SEC_C_MODE_CTR,
  .key_len = SEC_KEY_LEN_AES_128,
 },
 [SEC_C_AES_CTR_192] = {
     ENOMEM  err_free_hw_sgls
 .  ,
   ;

=
  sgl_current-  java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
s>sge_entries]lensg_dma_lensg;
  >+ sg_dma_len)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
 }java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
:
  sec_free_hw_sgl(sec_sglpsec_sgl);
* = ;
  .key_len = SEC_KEY_LEN_AES_128,
 },
 [SEC_C_AES_XTS_256 java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
  .c_alg = SEC_C_ALG_AES,
  const k,unsignedintkeylen
  .key_len = SEC_KEY_LEN_AES_256  * (tfm
 },
 struct dev>>dev_info-;
 },
}(ctx-)java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24

/*  
 * Mutex used to ensure safe operation of reference count of
 * alg providers
 */

static DEFINE_MUTEX(algs_lock!>keyjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
staticunsignedi active_devs

static void
     structsec_bd_info,
        enum sec_cipher_alg
{
 const struct sec_c_alg_cfg        u8,   )

 memset(req, 0, sizeof(*req));
 | >c_mode SEC_BD_W0_C_MODE_S
 > | >c_alg SEC_BD_W1_C_ALG_S
req- =cfg- <SEC_BD_W3_C_KEY_LEN_S
 break;

 req->cipher_key_addr_lo = lower_32_bits AES_KEYSIZE_192
 req-cipher_key_addr_hi= upper_32_bitsctx-);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

static EINVAL
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
  unsigned ,
       enum sec_cipher_alg alg)
{
 truct * =()java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
 struct * crypto_tfm_ctx);

 ctx-case:
  alg=SEC_C_AES_CBC_128
 java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
   c;
}

static
    )
{
 returnEINVAL
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
   const ,unsignedint)
  ;
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  dma_pool_free(info->hw_sgl_pool, sgl_current, psec_sgl);break;

  sgl_current
  =sgl_next_dma
 }
}

static int sec_alloc_and_fill_hw_sgl(;
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
           c  key unsigned intkeylen
 struct sec_dev_info*info
         gfp_t gfp
{
 struct sec_hw_sgl *sgl_current = NULL; ret
 struct  ) java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
   *java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
 structjava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 int(struct tfm

  !)
  returnverify_skcipher_des_key,)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44

 for_each_sg(sgl, sg, count, i) {
  sge_index = i % SEC_MAX_SGE_NUM;
  if (sge_index =static (struct *,
  sgl_next info-,
         gfp, &sgl_next_dma);
    verify_skcipher_des_key, ey?java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
    ret = -java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
           key unsignedint eylen
   }

   if (!sgl_current) { /* First one */
    *        SEC_C_3DES_ECB_192)
   java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  lse /* Chained */ /
    sgl_current->entry_sum_in_sgl = SEC_MAX_SGE_NUM;
  = ;
   >ext java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
  void(  el
   sgl_current = sgl_next;
       *)
  java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 s(>in >, )
  (sgl_in
 }
 >entry_sum_in_sgl  % ;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 *ec_sgl)> = ;

  ;

err_free_hw_sgls:
 sec_free_hw_sgl(*sec_sgl,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 *psec_sgl

 return ret;
}

static int sec_alg_skcipher_setkey(struct crypto_skcipher *tfm   * 2) No dependencies   *    to maintain order)
       const u8 *key, unsigned int keylen,
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
 structsec_queue_emptyqueue) 
  ret=sec_queue_sendqueue&>, );

 (&ctx->);
 if  /* Wait unti we can send then try again */
  /* rekeying */ java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
  memset(>)java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
 } else {
  /* new key */struct *)
  > (devSEC_MAX_CIPHER_KEY,
                      java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
 s *backlog_req
  m(ctx-lock
   return  *tx >;
  }
 }
(&>)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
 tfmkey ,)

 return 0;
}

static sec_alg_skcipher_setkey_aes_ecb  tfm,
        ;
{
 enumsec_cipher_algalg

 switch (dev " an lu dn,
 caseAES_KEYSIZE_128
 alg ;
  ;
 case AES_KEYSIZE_192:
  alg = SEC_C_AES_ECB_192;
  break;
 case AES_KEYSIZE_256:
 /
   * We need to muddle  * on the queue. Error will be reported so   * it should be java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 5
 ifsec_req_el-.  EC_BD_W0_DE
    sec_req_el-sgl_out
 }

 return sec_alg_skcipher_setkey(tfm, key, keylen, alg);
}

  (struct crypto_skcipher,
    const u8*ey nsigned int keylen
{
 enum sec_cipher_alg algjava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6

  (keylen) java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
  crypto_skcipher_ivsizeatfm),
  alg    > -
   crypto_skcipher_ivsize))
 case AES_KEYSIZE_192java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
   =SEC_C_AES_CBC_192;
  aseSEC_C_AES_CTR_128:
 caseSEC_C_AES_CTR_192
  algcase :
  break(>iv, 1)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
 default:
 r -;
 }

 
}

static  sec_alg_skcipher_setkey_aes_ctr(struct tfm,
        const u8!(&>>softqueue&
{
 enum sec_cipher_alg alg;

 switch (keylen) {
 case AES_KEYSIZE_128:
  alg = SEC_C_AES_CTR_128;
  break;
 case AES_KEYSIZE_192 if =0
  algSEC_C_AES_CTR_192
  break;
 caseAES_KEYSIZE_256
  alg   ret);
  break;
 default:
  return -EINVAL;
 }

 return sec_alg_skcipher_setkey(tfm, key, keylen,  /* We know there is space so this cannot fail */sec_queue_sendctx-queue &>,
}

static int sec_alg_skcipher_setkey_aes_xts(struct crypto_skcipher *}  (list_empty(ctx-backlog) {
  /  toverifythere is first /
{
 enum sec_cipher_algalg;
 int         typeofbacklog_req)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33

 ret = xts_verify_key(tfm,     backlog_req-num_elements ||java.lang.StringIndexOutOfBoundsException: Range [35, 36) out of bounds for length 35
 ifbacklog_req-num_elements))java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
  c(backlog_req-req_base,

 switch (keylen) {
 case AES_KEYSIZE_128 * 2:
     EINPROGRESS
  break;
  ES_KEYSIZE_256 :
  alg = SEC_C_AES_XTS_256;
  break;
 default:
  return -EINVAL
  

spin_unlock_bh>queue-queuelock;
}

static intsec_alg_skcipher_setkey_des_ecb(  tfm
        list_del&>head
{
 return verify_skcipher_des_key, ) :
       tfm, ey keylenSEC_C_DES_ECB_64)java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
}

static  sec_alg_skcipher_setkey_des_cbcstruct crypto_skciphertfm,
        const u8 (&sec_req-lock)java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
{
 return verify_skcipher_des_key( dma_unmap_single(dev,>,
        (tfm,, keylen,);
}

static int sec_alg_skcipher_setkey_3des_ecb(struct crypto_skcipher *tfm,
  *keyunsignedint )
{
 eturnverify_skcipher_des3_keytfm ) :
        sec_alg_skcipher_setkey(tfm, key, keylen,
           SEC_C_3DES_ECB_192_3KEY);
}

static sec_alg_skcipher_setkey_3des_cbccrypto_skcipher *,
       constu8*eyu int)
{
 return java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 2
        (tfm ,java.lang.StringIndexOutOfBoundsException: Range [48, 43) out of bounds for length 49
           SEC_C_3DES_CBC_192_3KEY
}

static void sec_alg_free_el(struct sec_request_el *el,
       sec_dev_info * *info)
{
 sec_free_hw_sgl(el-       intsteps,gfp_t)
 sec_free_hw_sglel-in el-dma_in,)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
k(>)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
 kfree(el- (!sizes
 kfreeel;
}

/* queuelock must be held */
static int sec_send_request(struct sec_request *sec_req, struct
{
 struct sec_request_el[  SEC_REQ_LIMIT
intret 0

 mutex_lock(sec_req-lock
 list_for_each_entry_safe(el,  return 0;
  /*
 * Add to hardware queue only under following circumstances
 * 1) Software and hardware queue empty so no chain dependencies
 * 2) No dependencies as new IV - (check software queue empty
 *    to maintain order)
 * 3) No dependencies because the mode does no chaining.
 *
 * In other cases first insert onto the software queue which
 * is then emptied as requests complete
 */

  if (queue-havesoftqueue||
      ( int steps, structscatterlist**splits
       sec_queue_emptyqueue))) {
   ret = sec_queue_sendjava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
 i ret=-) {
    /* Wait unti we can send then try again */
    /* DEAD if here - should not happen */-EINVAL
   ret =EBUSY
 if(*plits){
  java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
  } else splits_n  kcalloc(stepssizeof(),)
   (!*){
  }
 }
err_unlock:
 mutex_unlock(&sec_req->lock);

 return ret;
}

static void   ;
          structatter list  andafterjava.lang.StringIndexOutOfBoundsException: Range [49, 45) out of bounds for length 52
{
 struct         *splits, *split, s, gfp
            ret=ENOMEM
           );
 struct sec_request *sec_req
 struct sec_request *backlog_req;
 struct sec_request_el *sec_req_el, *nextrequest;
 struct java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 struct crypto_skcipher(*plits_nents
 struct(**plits
 :
 (dev sgl gl_len_in, DMA_BIDIRECTIONAL);

 sec_req_el = list_first_entry(&sec_req->elements, struct sec_request_el,
          head);
 icv_or_skey_en * Reverses the sec_map_and_split_sg call for messages not yet added to * the queues
  ;
 if (sec_resp->w1 & SEC_BD_W1_BD_INVALID || icv_or_skey_en == 3) {
  (,"Gotinvalidanswer %d\n",
   sec_resp->w1 & SEC_BD_W1_BD_INVALID,
   icv_or_skey_en);
  sec_req->err = -EINVAL;
 java.lang.StringIndexOutOfBoundsException: Range [4, 3) out of bounds for length 4
   * We need to muddle on to avoid getting stuck with elements
   * on the queue. Error will be reported so requester so
   * it should be able to handle appropriately.
   */
 }

 spin_lock_bh(&ctx->queue->queuelock);
 /* Put the IV in place for chained cases */
 switch (ctx->cipher_alg) {
 case SEC_C_AES_CBC_128:
 case SEC_C_AES_CBC_192:
 case SEC_C_AES_CBC_256:
  if (sec_req_el->req.w0 & SEC_BD_W0_DE)
   sg_pcopy_to_buffer(sec_req_el->sgl_out,
        sg_nents(sec_req_el->sgl_out),
        skreq->iv,
        crypto_skcipher_ivsize(atfm),
        sec_req_el->el_length -
        crypto_skcipher_ivsize(atfm));
  else
   sg_pcopy_to_buffer(sec_req_el->sgl_in,
        sg_nents(sec_req_el->sgl_in),
        skreq->iv,
        crypto_skcipher_ivsize(atfm),
        sec_req_el->el_length -
        crypto_skcipher_ivsize(atfm));
  /* No need to sync to the device as coherent DMA */
  break;
 case SEC_C_AES_CTR_128:
 case SEC_C_AES_CTR_192:
 case SEC_C_AES_CTR_256:
  crypto_inc(skreq->iv, 16);
  break;
 default:
  /* Do not update */
  break;
 }

 if (ctx->queue->havesoftqueue &&
     !kfifo_is_empty(&ctx->queue->softqueue) &&
     sec_queue_empty(ctx->queue)) {
  ret = kfifo_get(&ctx->queue->softqueue, &nextrequest);
  if (ret <= 0)
   dev_err(dev,
    "Error getting next element from kfifo %d\n",
    ret);
  else
   /* We know there is space so this cannot fail */
   sec_queue_send(ctx->queue, &nextrequest->req,
           nextrequest->sec_req);
 } else if (!list_empty(&ctx->backlog)) {
  /* Need to verify there is room first */
  backlog_req = list_first_entry(&ctx->backlog,
            typeof(*backlog_req),
            backlog_head);
  if (sec_queue_can_enqueue(ctx->queue,
      backlog_req->num_elements) ||
      (ctx->queue->havesoftqueue &&
       kfifo_avail(&ctx->queue->softqueue) >
       backlog_req->num_elements)) {
   sec_send_request(backlog_req, ctx->queue);
   crypto_request_complete(backlog_req->req_base,
      -EINPROGRESS);
   list_del(&backlog_req->backlog_head);
  }
 }
 spin_unlock_bh(&ctx->queue->queuelock);

 mutex_lock(&sec_req->lock);
 list_del(&sec_req_el->head);
 mutex_unlock(&sec_req->lock);
 sec_alg_free_el(sec_req_el, ctx->queue->dev_info);

 /*
 * Request is done.
 * The dance is needed as the lock is freed in the completion
 */

 mutex_lock(&sec_req->lock);
 done = list_empty(&sec_req->elements);
 mutex_unlock(&sec_req->lock);
 if (done) {
  if (crypto_skcipher_ivsize(atfm)) {
   dma_unmap_single(dev, sec_req->dma_iv,
      crypto_skcipher_ivsize(atfm),
      DMA_TO_DEVICE);
  }
  dma_unmap_sg(dev, skreq->src, sec_req->len_in,
        DMA_BIDIRECTIONAL);
  if (skreq->src != skreq->dst)
   dma_unmap_sg(dev, skreq->dst, sec_req->len_out,
         DMA_BIDIRECTIONAL);
  skcipher_request_complete(skreq, sec_req->err);
 }
}

void sec_alg_callback(struct sec_bd_info *resp, void *shadow)
{
 struct sec_request *sec_req = shadow;

 sec_req->cb(resp, sec_req->req_base);
}

static int sec_alg_alloc_and_calc_split_sizes(int length, size_t **split_sizes,
           int *steps, gfp_t gfp)
{
 size_t *sizes;
 int i;

 /* Split into suitable sized blocks */
 *steps = roundup(length, SEC_REQ_LIMIT) / SEC_REQ_LIMIT;
 sizes = kcalloc(*steps, sizeof(*sizes), gfp);
 if (!sizes)
  return -ENOMEM;

 for (i = 0; i < *steps - 1; i++)
  sizes[i] = SEC_REQ_LIMIT;
 sizes[*steps - 1] = length - SEC_REQ_LIMIT * (*steps - 1);
 *split_sizes = sizes;

 return 0;
}

  return ERR_PTR el->el_length req = &el->req memcpy(req, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   SEC_BD_W0_C_GRAN_SIZE_19_16_M
 req->w0 |= ((el_size >> 20)  SEC_BD_W0_C_GRAN_SIZE_21_20_M;
    int sgl_len_in,
    struct device *dev, gfp_t gfp)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
   ;

 count = dma_map_sg(dev, sgl, sgl_len_in, DMA_BIDIRECTIONAL);
 if (!count)
  return -EINVAL;

 * = (,sizeof( scatterlistjava.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 61
 if(*plits {
  ret = -ENOMEM;
  err_unmap_sg;
 }
 *  calloc, (int),g);
 if (!*splits_nents) {
  ret -;
  goto err_free_splits;
 }

 /* output the scatter list before and after this */
 fp_tgfp  >base &   :GFP_ATOMIC
         *splitsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 if (ret) {
  ret = -ENOMEM;
  goto err_free_splits_nents
 }

 return 0;

err_free_splits_nents:
 kfree*plits_nents
err_free_splits:
 (*);
err_unmap_sg:
 (dev ,sgl_len_in DMA_BIDIRECTIONAL)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55

 return retsec_req-cb=  sec_skcipher_alg_callback
}

/*
 * Reverses the sec_map_and_split_sg call for messages not yet added to
 * the queues.
 */

static void  * Future optimization.
    struct scatterlist **splits, int *splits_nents,
    int sgl_len_in, struct device *dev)
{
 intgoto;

 for (el->.cipher_iv_addr_lolower_32_bitssec_req->)java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
  ([i;
 kfree
 kfree

 dma_unmap_sg(dev  * we can't successfully * must succeed or fail atomically.
}

static struct sec_request_el
*sec_alg_alloc_and_fill_el(  *
 
      scatterlist*, intn_ents_in,
     scatterlistsgl_out,  n_ents_outjava.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
      struct sec_dev_info *info  * AND java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
{
 (>queue
 struct
 int lock_init&>>queuelock;

 el = kzalloc(sizeofstaticvoidsec_alg_skcipher_exit( crypto_skcipher tfm)
 if (!el)
   (-NOMEM)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
 >el_length el_size}
 req = &el->req;
 memcpy(req .ra_driver_name = "hisi_sec_3des_cbc",

 req->w0 &= ~SEC_BD_W0_CIPHER_M;
 if (encrypt)
  req->w0 |= SEC_CIPHER_ENCRYPT << SEC_BD_W0_CIPHER_S;
 lse
  req->w0 |= SEC_CIPHER_DECRYPT << SEC_BD_W0_CIPHER_S;

 req-> . =C |
 req->w0 |= ((el_size >> 16)  .cra_blocksize  ,
  SEC_BD_W0_C_GRAN_SIZE_19_16_M;

 req->w0 &= ~SEC_BD_W0_C_GRAN_SIZE_21_20_M;
 req->w0     . = 0java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
  SEC_BD_W0_C_GRAN_SIZE_21_20_M;

 /* Writing whole u32 so no need to take care of masking */
 req->w2 = ((1 << SEC_BD_W2_GRAN_NUM_S) & SEC_BD_W2_GRAN_NUM_M) |
  ((el_size << SEC_BD_W2_C_GRAN_SIZE_15_0_S) &
   SEC_BD_W2_C_GRAN_SIZE_15_0_M);

 req->w3 &= ~SEC_BD_W3_CIPHER_LEN_OFFSET_M;
 req->w1 |= SEC_BD_W1_ADDR_TYPE;

 el->sgl_in = sgl_in;

 ret = sec_alloc_and_fill_hw_sgl(&el->in, &el->dma_in, el->sgl_in,
     n_ents_in, info, gfp);
 if (ret)
  goto err_free_el;

 req->data_addr_lo = lower_32_bits(el->dma_in);
 req->data_addr_hi = upper_32_bits(el->dma_in);

 if (different_dest) {
  el->sgl_out = sgl_out;
  ret = sec_alloc_and_fill_hw_sgl(&el->out, &el->dma_out,
      el->sgl_out,
      n_ents_out, info, gfp);
  if (ret)
   goto err_free_hw_sgl_in;

  req->w0 |= SEC_BD_W0_DE;
  req->cipher_destin_addr_lo = lower_32_bits(el->dma_out);
  req->cipher_destin_addr_hi = upper_32_bits(el->dma_out);

 } else {
  req->w0 &= ~SEC_BD_W0_DE;
  req->cipher_destin_addr_lo = lower_32_bits(el->dma_in);
  req->cipher_destin_addr_hi = upper_32_bits(el->dma_in);
 }

 return el;

err_free_hw_sgl_in:
 sec_free_hw_sgl(el->in, el->dma_in, info);
err_free_el:
 kfree(el);

 return ERR_PTR(ret);
}

static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
       bool encrypt)
{
 struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(skreq);
 struct crypto_tfm *tfm = crypto_skcipher_tfm(atfm);
 struct sec_alg_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 struct sec_queue *queue = ctx->queue;
 struct sec_request *sec_req = skcipher_request_ctx(skreq);
 struct sec_dev_info *info = queue->dev_info;
 int i, ret, steps;
 size_t *split_sizes;
 struct scatterlist **splits_in;
 struct scatterlist **splits_out = NULL;
 int *splits_in_nents;
 int *splits_out_nents = NULL;
 struct sec_request_el *el, *temp;
 bool split = skreq->src != skreq->dst;
 gfp_t gfp = skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC;

 mutex_init(&sec_req->lock);
 sec_req->req_base = &skreq->base;
 sec_req->err = 0;
 /* SGL mapping out here to allow us to break it up as necessary */
 sec_req->len_in = sg_nents(skreq->src);

 ret = sec_alg_alloc_and_calc_split_sizes(skreq->cryptlen, &split_sizes,
       &steps, gfp);
 if (ret)
  return ret;
 sec_req->num_elements = steps;
 ret = sec_map_and_split_sg(skreq->src, split_sizes, steps, &splits_in,
       &splits_in_nents, sec_req->len_in,
       info->dev, gfp);
 if (ret)
  goto err_free_split_sizes;

 if (split) {
  sec_req->len_out = sg_nents(skreq->dst);
  ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps,
        &splits_out, &splits_out_nents,
        sec_req->len_out, info->dev, gfp);
  if (ret)
   goto err_unmap_in_sg;
 }
 /* Shared info stored in seq_req - applies to all BDs */
 sec_req->tfm_ctx = ctx;
 sec_req->cb = sec_skcipher_alg_callback;
 INIT_LIST_HEAD(&sec_req->elements);

 /*
 * Future optimization.
 * In the chaining case we can't use a dma pool bounce buffer
 * but in the case where we know there is no chaining we can
 */

 if (crypto_skcipher_ivsize(atfm)) {
  sec_req->dma_iv = dma_map_single(info->dev, skreq->iv,
       crypto_skcipher_ivsize(atfm),
       DMA_TO_DEVICE);
  if (dma_mapping_error(info->dev, sec_req->dma_iv)) {
   ret = -ENOMEM;
   goto err_unmap_out_sg;
  }
 }

 /* Set them all up then queue - cleaner error handling. */
 for (i = 0; i < steps; i++) {
  el = sec_alg_alloc_and_fill_el(&ctx->req_template,
            encrypt ? 1 : 0,
            split_sizes[i],
            skreq->src != skreq->dst,
            splits_in[i], splits_in_nents[i],
            split ? splits_out[i] : NULL,
            split ? splits_out_nents[i] : 0,
            info, gfp);
  if (IS_ERR(el)) {
   ret = PTR_ERR(el);
   goto err_free_elements;
  }
  el->req.cipher_iv_addr_lo = lower_32_bits(sec_req->dma_iv);
  el->req.cipher_iv_addr_hi = upper_32_bits(sec_req->dma_iv);
  el->sec_req = sec_req;
  list_add_tail(&el->head, &sec_req->elements);
 }

 /*
 * Only attempt to queue if the whole lot can fit in the queue -
 * we can't successfully cleanup after a partial queing so this
 * must succeed or fail atomically.
 *
 * Big hammer test of both software and hardware queues - could be
 * more refined but this is unlikely to happen so no need.
 */


 /* Grab a big lock for a long time to avoid concurrency issues */
 spin_lock_bh(&queue->queuelock);

 /*
 * Can go on to queue if we have space in either:
 * 1) The hardware queue and no software queue
 * 2) The software queue
 * AND there is nothing in the backlog.  If there is backlog we
 * have to only queue to the backlog queue and return busy.
 */

 if ((!sec_queue_can_enqueue(queue, steps) &&
      (!queue->havesoftqueue ||
       kfifo_avail(&queue->softqueue) > steps)) ||
     !list_empty(&ctx->backlog)) {
  ret = -EBUSY;
  if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
   list_add_tail(&sec_req->backlog_head, &ctx->backlog);
   spin_unlock_bh(&queue->queuelock);
   goto out;
  }

  spin_unlock_bh(&queue->queuelock);
  goto err_free_elements;
 }
 ret = sec_send_request(sec_req, queue);
 spin_unlock_bh(&queue->queuelock);
 if (ret)
  goto err_free_elements;

 ret = -EINPROGRESS;
out:
 /* Cleanup - all elements in pointer arrays have been copied */
 kfree(splits_in_nents);
 kfree(splits_in);
 kfree(splits_out_nents);
 kfree(splits_out);
 kfree(split_sizes);
 return ret;

err_free_elements:
 list_for_each_entry_safe(el, temp, &sec_req->elements, head) {
  list_del(&el->head);
  sec_alg_free_el(el, info);
 }
 if (crypto_skcipher_ivsize(atfm))
  dma_unmap_single(info->dev, sec_req->dma_iv,
     crypto_skcipher_ivsize(atfm),
     DMA_BIDIRECTIONAL);
err_unmap_out_sg:
 if (split)
  sec_unmap_sg_on_err(skreq->dst, steps, splits_out,
        splits_out_nents, sec_req->len_out,
        info->dev);
err_unmap_in_sg:
 sec_unmap_sg_on_err(skreq->src, steps, splits_in, splits_in_nents,
       sec_req->len_in, info->dev);
err_free_split_sizes:
 kfree(split_sizes);

 return ret;
}

static int sec_alg_skcipher_encrypt(struct skcipher_request *req)
{
 return sec_alg_skcipher_crypto(req, true);
}

static int sec_alg_skcipher_decrypt(struct skcipher_request *req)
{
 return sec_alg_skcipher_crypto(req, false);
}

static int sec_alg_skcipher_init(struct crypto_skcipher *tfm)
{
 struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);

 mutex_init(&ctx->lock);
 INIT_LIST_HEAD(&ctx->backlog);
 crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_request));

 ctx->queue = sec_queue_alloc_start_safe();
 if (IS_ERR(ctx->queue))
  return PTR_ERR(ctx->queue);

 spin_lock_init(&ctx->queue->queuelock);
 ctx->queue->havesoftqueue = false;

 return 0;
}

static void sec_alg_skcipher_exit(struct crypto_skcipher *tfm)
{
 struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
 struct device *dev = ctx->queue->dev_info->dev;

 if (ctx->key) {
  memzero_explicit(ctx->key, SEC_MAX_CIPHER_KEY);
  dma_free_coherent(dev, SEC_MAX_CIPHER_KEY, ctx->key,
      ctx->pkey);
 }
 sec_queue_stop_release(ctx->queue);
}

static int sec_alg_skcipher_init_with_queue(struct crypto_skcipher *tfm)
{
 struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
 int ret;

 ret = sec_alg_skcipher_init(tfm);
 if (ret)
  return ret;

 INIT_KFIFO(ctx->queue->softqueue);
 ret = kfifo_alloc(&ctx->queue->softqueue, 512, GFP_KERNEL);
 if (ret) {
  sec_alg_skcipher_exit(tfm);
  return ret;
 }
 ctx->queue->havesoftqueue = true;

 return 0;
}

static void sec_alg_skcipher_exit_with_queue(struct crypto_skcipher *tfm)
{
 struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);

 kfifo_free(&ctx->queue->softqueue);
 sec_alg_skcipher_exit(tfm);
}

static struct skcipher_alg sec_algs[] = {
 {
  .base = {
   .cra_name = "ecb(aes)",
   .cra_driver_name = "hisi_sec_aes_ecb",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = AES_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init,
  .exit = sec_alg_skcipher_exit,
  .setkey = sec_alg_skcipher_setkey_aes_ecb,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = AES_MIN_KEY_SIZE,
  .max_keysize = AES_MAX_KEY_SIZE,
  .ivsize = 0,
 }, {
  .base = {
   .cra_name = "cbc(aes)",
   .cra_driver_name = "hisi_sec_aes_cbc",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = AES_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init_with_queue,
  .exit = sec_alg_skcipher_exit_with_queue,
  .setkey = sec_alg_skcipher_setkey_aes_cbc,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = AES_MIN_KEY_SIZE,
  .max_keysize = AES_MAX_KEY_SIZE,
  .ivsize = AES_BLOCK_SIZE,
 }, {
  .base = {
   .cra_name = "ctr(aes)",
   .cra_driver_name = "hisi_sec_aes_ctr",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = AES_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init_with_queue,
  .exit = sec_alg_skcipher_exit_with_queue,
  .setkey = sec_alg_skcipher_setkey_aes_ctr,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = AES_MIN_KEY_SIZE,
  .max_keysize = AES_MAX_KEY_SIZE,
  .ivsize = AES_BLOCK_SIZE,
 }, {
  .base = {
   .cra_name = "xts(aes)",
   .cra_driver_name = "hisi_sec_aes_xts",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = AES_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init,
  .exit = sec_alg_skcipher_exit,
  .setkey = sec_alg_skcipher_setkey_aes_xts,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = 2 * AES_MIN_KEY_SIZE,
  .max_keysize = 2 * AES_MAX_KEY_SIZE,
  .ivsize = AES_BLOCK_SIZE,
 }, {
 /* Unable to find any test vectors so untested */
  .base = {
   .cra_name = "ecb(des)",
   .cra_driver_name = "hisi_sec_des_ecb",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = DES_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init,
  .exit = sec_alg_skcipher_exit,
  .setkey = sec_alg_skcipher_setkey_des_ecb,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = DES_KEY_SIZE,
  .max_keysize = DES_KEY_SIZE,
  .ivsize = 0,
 }, {
  .base = {
   .cra_name = "cbc(des)",
   .cra_driver_name = "hisi_sec_des_cbc",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = DES_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init_with_queue,
  .exit = sec_alg_skcipher_exit_with_queue,
  .setkey = sec_alg_skcipher_setkey_des_cbc,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = DES_KEY_SIZE,
  .max_keysize = DES_KEY_SIZE,
  .ivsize = DES_BLOCK_SIZE,
 }, {
  .base = {
   .cra_name = "cbc(des3_ede)",
   .cra_driver_name = "hisi_sec_3des_cbc",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = DES3_EDE_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init_with_queue,
  .exit = sec_alg_skcipher_exit_with_queue,
  .setkey = sec_alg_skcipher_setkey_3des_cbc,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = DES3_EDE_KEY_SIZE,
  .max_keysize = DES3_EDE_KEY_SIZE,
  .ivsize = DES3_EDE_BLOCK_SIZE,
 }, {
  .base = {
   .cra_name = "ecb(des3_ede)",
   .cra_driver_name = "hisi_sec_3des_ecb",
   .cra_priority = 4001,
   .cra_flags = CRYPTO_ALG_ASYNC |
         CRYPTO_ALG_ALLOCATES_MEMORY,
   .cra_blocksize = DES3_EDE_BLOCK_SIZE,
   .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx),
   .cra_alignmask = 0,
   .cra_module = THIS_MODULE,
  },
  .init = sec_alg_skcipher_init,
  .exit = sec_alg_skcipher_exit,
  .setkey = sec_alg_skcipher_setkey_3des_ecb,
  .decrypt = sec_alg_skcipher_decrypt,
  .encrypt = sec_alg_skcipher_encrypt,
  .min_keysize = DES3_EDE_KEY_SIZE,
  .max_keysize = DES3_EDE_KEY_SIZE,
  .ivsize = 0,
 }
};

int sec_algs_register(void)
{
 int ret = 0;

 mutex_lock(&algs_lock);
 if (++active_devs != 1)
  goto unlock;

 ret = crypto_register_skciphers(sec_algs, ARRAY_SIZE(sec_algs));
 if (ret)
  --active_devs;
unlock:
 mutex_unlock(&algs_lock);

 return ret;
}

void sec_algs_unregister(void)
{
 mutex_lock(&algs_lock);
 if (--active_devs != 0)
  goto unlock;
 crypto_unregister_skciphers(sec_algs, ARRAY_SIZE(sec_algs));

unlock:
 mutex_unlock(&algs_lock);
}

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

¤ 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.0.12Bemerkung:  ¤

*Bot Zugriff






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.