LCOV - code coverage report
Current view: top level - drivers/common/dpaax/caamflib/desc - sdap.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 293 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 9 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 126 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2020-2023 NXP
       3                 :            :  */
       4                 :            : 
       5                 :            : #ifndef __DESC_SDAP_H__
       6                 :            : #define __DESC_SDAP_H__
       7                 :            : 
       8                 :            : #include "rta.h"
       9                 :            : #include "common.h"
      10                 :            : #include "pdcp.h"
      11                 :            : 
      12                 :            : /* The file defines all the functions to do PDCP without protocol support in
      13                 :            :  * SEC
      14                 :            :  */
      15                 :            : 
      16                 :            : /* Enable SDAP support */
      17                 :            : #define SDAP_SUPPORT
      18                 :            : #ifdef SDAP_SUPPORT
      19                 :            : #define SDAP_BYTE_SIZE 1
      20                 :            : #define SDAP_BITS_SIZE (SDAP_BYTE_SIZE * 8)
      21                 :            : #endif
      22                 :            : 
      23                 :            : /**
      24                 :            :  * rta_inline_pdcp_query() - Provide indications if a key can be passed as
      25                 :            :  *                           immediate data or shall be referenced in a
      26                 :            :  *                           shared descriptor.
      27                 :            :  * Return: 0 if data can be inlined or 1 if referenced.
      28                 :            :  */
      29                 :            : static inline int
      30                 :            : rta_inline_pdcp_sdap_query(enum auth_type_pdcp auth_alg,
      31                 :            :                       enum cipher_type_pdcp cipher_alg,
      32                 :            :                       __rte_unused enum pdcp_sn_size sn_size,
      33                 :            :                       __rte_unused int8_t hfn_ovd)
      34                 :            : {
      35                 :          0 :         if ((cipher_alg != PDCP_CIPHER_TYPE_NULL) &&
      36         [ #  # ]:          0 :                         (auth_alg != PDCP_AUTH_TYPE_NULL))
      37                 :            :                 return 2;
      38                 :            :         else
      39                 :            :                 return 0;
      40                 :            : }
      41                 :            : 
      42                 :          0 : static inline void key_loading_opti(struct program *p,
      43                 :            :                                     struct alginfo *cipherdata,
      44                 :            :                                     struct alginfo *authdata)
      45                 :            : {
      46                 :            :         LABEL(lbl_skip_key_loading_jump);
      47                 :            :         REFERENCE(ref_skip_key_loading_jump);
      48                 :            : 
      49                 :            :         /* Optimisation to bypass key loading (and decryption of the keys):
      50                 :            :          * Jump command testing:
      51                 :            :          * - SHRD: Descriptor is shared
      52                 :            :          * - SELF: The shared descriptor is in the same DECO
      53                 :            :          * - BOTH: The Class 1 and 2 CHA have finished
      54                 :            :          * -> If this is true, we jump and skip loading of the keys as they are
      55                 :            :          *    already loaded
      56                 :            :          */
      57                 :            :         ref_skip_key_loading_jump =
      58                 :          0 :                 JUMP(p, lbl_skip_key_loading_jump, LOCAL_JUMP, ALL_TRUE,
      59                 :            :                      SHRD | SELF | BOTH);
      60                 :            : 
      61                 :            :         /* Load the keys */
      62         [ #  # ]:          0 :         if (cipherdata) {
      63                 :          0 :                 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
      64                 :            :                     cipherdata->keylen, INLINE_KEY(cipherdata));
      65                 :            :         }
      66                 :            : 
      67         [ #  # ]:          0 :         if (authdata) {
      68                 :          0 :                 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
      69                 :            :                     authdata->keylen, INLINE_KEY(authdata));
      70                 :            :         }
      71                 :            : 
      72                 :            :         /* Save the place where we want the jump to go */
      73                 :            :         SET_LABEL(p, lbl_skip_key_loading_jump);
      74                 :            :         /* Update the jump command with the position where to jump */
      75                 :          0 :         PATCH_JUMP(p, ref_skip_key_loading_jump, lbl_skip_key_loading_jump);
      76                 :          0 : }
      77                 :            : 
      78                 :          0 : static inline int pdcp_sdap_get_sn_parameters(enum pdcp_sn_size sn_size,
      79                 :            :                                               bool swap, uint32_t *offset,
      80                 :            :                                               uint32_t *length,
      81                 :            :                                               uint32_t *sn_mask)
      82                 :            : {
      83   [ #  #  #  #  :          0 :         switch (sn_size) {
                   #  # ]
      84                 :          0 :         case PDCP_SN_SIZE_5:
      85                 :          0 :                 *offset = 7;
      86                 :          0 :                 *length = 1;
      87         [ #  # ]:          0 :                 *sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
      88                 :            :                                              PDCP_C_PLANE_SN_MASK_BE;
      89                 :          0 :                 break;
      90                 :          0 :         case PDCP_SN_SIZE_7:
      91                 :          0 :                 *offset = 7;
      92                 :          0 :                 *length = 1;
      93         [ #  # ]:          0 :                 *sn_mask = (swap == false) ? PDCP_7BIT_SN_MASK :
      94                 :            :                                              PDCP_7BIT_SN_MASK_BE;
      95                 :          0 :                 break;
      96                 :          0 :         case PDCP_SN_SIZE_12:
      97                 :          0 :                 *offset = 6;
      98                 :          0 :                 *length = 2;
      99         [ #  # ]:          0 :                 *sn_mask = (swap == false) ? PDCP_12BIT_SN_MASK :
     100                 :            :                                              PDCP_12BIT_SN_MASK_BE;
     101                 :          0 :                 break;
     102                 :          0 :         case PDCP_SN_SIZE_15:
     103                 :          0 :                 *offset = 6;
     104                 :          0 :                 *length = 2;
     105         [ #  # ]:          0 :                 *sn_mask = (swap == false) ? PDCP_U_PLANE_15BIT_SN_MASK :
     106                 :            :                                              PDCP_U_PLANE_15BIT_SN_MASK_BE;
     107                 :          0 :                 break;
     108                 :          0 :         case PDCP_SN_SIZE_18:
     109                 :          0 :                 *offset = 5;
     110                 :          0 :                 *length = 3;
     111         [ #  # ]:          0 :                 *sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
     112                 :            :                                              PDCP_U_PLANE_18BIT_SN_MASK_BE;
     113                 :          0 :                 break;
     114                 :          0 :         default:
     115                 :          0 :                 pr_err("Invalid sn_size for %s\n", __func__);
     116                 :          0 :                 return -ENOTSUP;
     117                 :            :         }
     118                 :            : 
     119                 :            : #ifdef SDAP_SUPPORT
     120                 :          0 :         *length += SDAP_BYTE_SIZE;
     121                 :          0 :         *offset -= SDAP_BYTE_SIZE;
     122                 :            : #endif
     123                 :            : 
     124                 :          0 :         return 0;
     125                 :            : }
     126                 :            : 
     127                 :          0 : static inline int pdcp_sdap_insert_no_int_op(struct program *p,
     128                 :            :                                              bool swap __maybe_unused,
     129                 :            :                                              struct alginfo *cipherdata,
     130                 :            :                                              unsigned int dir,
     131                 :            :                                              enum pdcp_sn_size sn_size,
     132                 :            :                                              enum pdb_type_e pdb_type)
     133                 :            : {
     134                 :            :         int op;
     135                 :          0 :         uint32_t sn_mask = 0;
     136                 :          0 :         uint32_t length = 0;
     137                 :          0 :         uint32_t offset = 0;
     138                 :            :         int hfn_bearer_dir_offset_in_descbuf =
     139                 :            :                 (pdb_type == PDCP_PDB_TYPE_FULL_PDB) ?
     140         [ #  # ]:          0 :                         FULL_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET :
     141                 :            :                         REDUCED_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET;
     142                 :            : 
     143         [ #  # ]:          0 :         if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
     144                 :            :                                         &sn_mask))
     145                 :            :                 return -ENOTSUP;
     146                 :            : 
     147                 :            :         /* Load key */
     148                 :          0 :         key_loading_opti(p, cipherdata, NULL);
     149                 :            : 
     150                 :          0 :         SEQLOAD(p, MATH0, offset, length, 0);
     151                 :          0 :         JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
     152                 :            : #ifdef SDAP_SUPPORT
     153         [ #  # ]:          0 :         rta_mathi(p, MATH0,
     154                 :            :                   ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
     155                 :            :                   SDAP_BITS_SIZE, MATH1, 8, 0);
     156                 :          0 :         MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     157                 :            : #else
     158                 :            :         MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     159                 :            : #endif
     160                 :            : 
     161                 :          0 :         SEQSTORE(p, MATH0, offset, length, 0);
     162                 :            : 
     163                 :          0 :         MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
     164                 :          0 :         MOVEB(p, DESCBUF, hfn_bearer_dir_offset_in_descbuf,
     165                 :            :                         MATH2, 0, 8, WAITCOMP | IMMED);
     166                 :          0 :         MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
     167                 :            : 
     168                 :          0 :         MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
     169                 :          0 :         MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
     170                 :            : 
     171                 :          0 :         SEQFIFOSTORE(p, MSG, 0, 0, VLF);
     172                 :            : 
     173                 :          0 :         op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC;
     174   [ #  #  #  # ]:          0 :         switch (cipherdata->algtype) {
     175                 :          0 :         case PDCP_CIPHER_TYPE_SNOW:
     176                 :            :                 /* Copy the IV */
     177                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
     178                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
     179                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
     180                 :          0 :                 break;
     181                 :            : 
     182                 :          0 :         case PDCP_CIPHER_TYPE_AES:
     183                 :            :                 /* The first 64 bits are 0 */
     184                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED);
     185                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR,
     186                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
     187                 :          0 :                 break;
     188                 :            : 
     189                 :          0 :         case PDCP_CIPHER_TYPE_ZUC:
     190                 :            :                 /* The LSB and MSB is the same for ZUC context */
     191                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
     192                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
     193                 :            : 
     194                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8,
     195                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
     196                 :          0 :                 break;
     197                 :            : 
     198                 :          0 :         default:
     199                 :          0 :                 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
     200                 :            :                        "pdcp_sdap_insert_15bit_op", cipherdata->algtype);
     201                 :          0 :                 return -EINVAL;
     202                 :            :         }
     203                 :            : 
     204                 :          0 :         SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
     205                 :            : 
     206                 :          0 :         return 0;
     207                 :            : }
     208                 :            : 
     209                 :            : static inline int
     210                 :          0 : pdcp_sdap_insert_enc_only_op(struct program *p, bool swap __maybe_unused,
     211                 :            :                              struct alginfo *cipherdata,
     212                 :            :                              struct alginfo *authdata __maybe_unused,
     213                 :            :                              unsigned int dir, enum pdcp_sn_size sn_size,
     214                 :            :                              enum pdb_type_e pdb_type)
     215                 :            : {
     216                 :          0 :         uint32_t offset = 0, length = 0, sn_mask = 0;
     217                 :            :         int hfn_bearer_dir_offset_in_descbuf =
     218                 :            :                 (pdb_type == PDCP_PDB_TYPE_FULL_PDB) ?
     219         [ #  # ]:          0 :                         FULL_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET :
     220                 :            :                         REDUCED_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET;
     221                 :            : 
     222         [ #  # ]:          0 :         if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
     223                 :            :                                         &sn_mask))
     224                 :            :                 return -ENOTSUP;
     225                 :            : 
     226                 :            :         /* Load key */
     227                 :          0 :         key_loading_opti(p, cipherdata, NULL);
     228                 :            : 
     229                 :            :         /* Load header */
     230                 :          0 :         SEQLOAD(p, MATH0, offset, length, 0);
     231                 :          0 :         JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
     232                 :            : 
     233                 :            : #ifdef SDAP_SUPPORT
     234         [ #  # ]:          0 :         rta_mathi(p, MATH0,
     235                 :            :                   ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
     236                 :            :                   SDAP_BITS_SIZE, MATH1, 8, 0);
     237                 :          0 :         MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     238                 :            : #else
     239                 :            :         MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     240                 :            : #endif
     241                 :            : 
     242                 :            :         /* Word (32 bit) swap */
     243                 :          0 :         MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
     244                 :            :         /* Load words from PDB: word 02 (HFN) + word 03 (bearer_dir)*/
     245                 :          0 :         MOVEB(p, DESCBUF, hfn_bearer_dir_offset_in_descbuf,
     246                 :            :                         MATH2, 0, 8, WAITCOMP | IMMED);
     247                 :            :         /* Create basic IV */
     248                 :          0 :         MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
     249                 :            : 
     250                 :            :         /* Write header */
     251                 :          0 :         SEQSTORE(p, MATH0, offset, length, 0);
     252                 :            : 
     253                 :          0 :         MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
     254                 :            : 
     255         [ #  # ]:          0 :         if (dir == OP_TYPE_ENCAP_PROTOCOL)
     256                 :          0 :                 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
     257                 :            :         else
     258                 :          0 :                 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
     259                 :            : 
     260   [ #  #  #  # ]:          0 :         switch (cipherdata->algtype) {
     261                 :          0 :         case PDCP_CIPHER_TYPE_SNOW:
     262                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
     263                 :          0 :                 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
     264                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
     265                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
     266                 :            :                               dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
     267                 :            :                                                               DIR_DEC);
     268                 :          0 :                 break;
     269                 :            : 
     270                 :          0 :         case PDCP_CIPHER_TYPE_AES:
     271                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED);
     272                 :            : 
     273                 :          0 :                 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
     274                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR,
     275                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
     276                 :            :                               dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
     277                 :            :                                                               DIR_DEC);
     278                 :          0 :                 break;
     279                 :            : 
     280                 :          0 :         case PDCP_CIPHER_TYPE_ZUC:
     281                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
     282                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
     283                 :            : 
     284                 :          0 :                 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
     285                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8,
     286                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
     287                 :            :                               dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
     288                 :            :                                                               DIR_DEC);
     289                 :          0 :                 break;
     290                 :            : 
     291                 :          0 :         default:
     292                 :          0 :                 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
     293                 :            :                        "pdcp_sdap_insert_enc_only_op", cipherdata->algtype);
     294                 :          0 :                 return -EINVAL;
     295                 :            :         }
     296                 :            : 
     297         [ #  # ]:          0 :         if (dir == OP_TYPE_ENCAP_PROTOCOL) {
     298                 :          0 :                 SEQFIFOLOAD(p, MSG1, 0, VLF);
     299                 :          0 :                 FIFOLOAD(p, MSG1, PDCP_NULL_INT_MAC_I_VAL, 4,
     300                 :            :                          LAST1 | FLUSH1 | IMMED);
     301                 :            :         } else {
     302                 :          0 :                 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
     303                 :          0 :                 MOVE(p, OFIFO, 0, MATH1, 4, PDCP_MAC_I_LEN, WAITCOMP | IMMED);
     304                 :          0 :                 MATHB(p, MATH1, XOR, PDCP_NULL_INT_MAC_I_VAL, NONE, 4, IMMED2);
     305                 :          0 :                 JUMP(p, PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS, HALT_STATUS,
     306                 :            :                      ALL_FALSE, MATH_Z);
     307                 :            :         }
     308                 :            : 
     309                 :            :         return 0;
     310                 :            : }
     311                 :            : 
     312                 :            : /*
     313                 :            :  * This function leverage the use of in/out snooping as SNOW and ZUC both
     314                 :            :  * have a class 1 and class 2 CHA. It also supports AES as cipher.
     315                 :            :  * Supported:
     316                 :            :  *  - cipher:
     317                 :            :  *      - AES-CTR
     318                 :            :  *      - SNOW F8
     319                 :            :  *      - ZUC F8
     320                 :            :  *  - authentication
     321                 :            :  *      - SNOW F8
     322                 :            :  *      - ZUC F8
     323                 :            :  */
     324                 :            : static inline int
     325                 :          0 : pdcp_sdap_insert_snoop_op(struct program *p, bool swap __maybe_unused,
     326                 :            :                           struct alginfo *cipherdata, struct alginfo *authdata,
     327                 :            :                           unsigned int dir, enum pdcp_sn_size sn_size,
     328                 :            :                           enum pdb_type_e pdb_type)
     329                 :            : {
     330                 :          0 :         uint32_t offset = 0, length = 0, sn_mask = 0;
     331                 :            :         uint32_t int_op_alg = 0;
     332                 :            :         uint32_t int_op_aai = 0;
     333                 :            :         uint32_t cipher_op_alg = 0;
     334                 :            :         uint32_t cipher_op_aai = 0;
     335                 :            :         int hfn_bearer_dir_offset_in_descbuf =
     336                 :            :                 (pdb_type == PDCP_PDB_TYPE_FULL_PDB) ?
     337         [ #  # ]:          0 :                         FULL_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET :
     338                 :            :                         REDUCED_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET;
     339                 :            : 
     340         [ #  # ]:          0 :         if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
     341                 :            :                                         &sn_mask))
     342                 :            :                 return -ENOTSUP;
     343                 :            : 
     344         [ #  # ]:          0 :         if (dir == OP_TYPE_ENCAP_PROTOCOL)
     345                 :          0 :                 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
     346                 :            : 
     347                 :          0 :         key_loading_opti(p, cipherdata, authdata);
     348                 :            : 
     349                 :            :         /* Load the PDCP header from the input data
     350                 :            :          * Note: SEQINSZ is decremented by length
     351                 :            :          */
     352                 :          0 :         SEQLOAD(p, MATH0, offset, length, 0);
     353                 :            :         /* Wait the SN is loaded */
     354                 :          0 :         JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
     355                 :            : 
     356                 :            :         /* Pass the PDCP header to integrity block */
     357                 :          0 :         MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
     358                 :            : 
     359                 :            : #ifdef SDAP_SUPPORT
     360                 :            :         /* If SDAP is enabled, the least significant byte is the SDAP header
     361                 :            :          * Remove it by shifting the register
     362                 :            :          */
     363         [ #  # ]:          0 :         rta_mathi(p, MATH0,
     364                 :            :                   ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
     365                 :            :                   SDAP_BITS_SIZE, MATH1, 8, 0);
     366                 :            :         /* Mask the PDCP header to keep only the SN */
     367                 :          0 :         MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     368                 :            : #else
     369                 :            :         /* Mask the PDCP header to keep only the SN */
     370                 :            :         MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     371                 :            : #endif
     372                 :            : 
     373                 :            :         /* Do a byte swap, it places the SN in upper part of the MATH reg */
     374                 :          0 :         MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
     375                 :            : 
     376                 :            :         /* Load the HFN / Beare / Dir from the PDB
     377                 :            :          * CAAM word are 32bit hence loading 8 byte loads 2 words:
     378                 :            :          *  - The HFN at offset hfn_bearer_dir_offset_in_descbuf
     379                 :            :          *  - The Bearer / Dir at next word
     380                 :            :          */
     381                 :          0 :         MOVEB(p, DESCBUF, hfn_bearer_dir_offset_in_descbuf,
     382                 :            :                         MATH2, 0, 8, WAITCOMP | IMMED);
     383                 :            : 
     384                 :            :         /* Create the 4 first byte of the ICV by or-ing the math registers */
     385                 :          0 :         MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
     386                 :            : 
     387                 :            :         /* Set the IV of class 1 CHA */
     388         [ #  # ]:          0 :         if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
     389                 :          0 :                 MOVEB(p, MATH1, 0, CONTEXT1, 16, 8, IMMED);
     390                 :            :         } else {
     391                 :            :                 /* Set the IV for the confidentiality CHA */
     392                 :          0 :                 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
     393                 :            :         }
     394                 :            : 
     395                 :            :         /* Set the IV of class 2 CHA */
     396         [ #  # ]:          0 :         if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) {
     397                 :            :                 /* Set the IV for the integrity CHA */
     398                 :          0 :                 MOVEB(p, MATH1, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
     399         [ #  # ]:          0 :         } else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) {
     400                 :          0 :                 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, WAITCOMP | IMMED);
     401                 :            : 
     402                 :            :                 /* Generate the bottom snow IV for integrity
     403                 :            :                  * Note: MATH1 lowest 32bits is as follow:
     404                 :            :                  * | bearer (5) | Dir (1) | zero (26) |
     405                 :            :                  * the resulting math regs will be:
     406                 :            :                  *               MATH3                           MATH2
     407                 :            :                  * | zero (5) | Dir (1) | zero (26) | | Bearer (5) | zero (27) |
     408                 :            :                  */
     409         [ #  # ]:          0 :                 if (swap == false) {
     410                 :          0 :                         MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK),
     411                 :            :                               MATH2, 4, IMMED2);
     412                 :          0 :                         MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK),
     413                 :            :                               MATH3, 4, IMMED2);
     414                 :            :                 } else {
     415                 :          0 :                         MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE),
     416                 :            :                               MATH2, 4, IMMED2);
     417                 :          0 :                         MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE),
     418                 :            :                               MATH3, 4, IMMED2);
     419                 :            :                 }
     420                 :            :                 /* Word swap MATH3 reg */
     421                 :          0 :                 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
     422                 :            : 
     423                 :            :                 /* Don't understand, seems to be doing a move of 12 byte
     424                 :            :                  * (read MATH2 and overread MATH3)
     425                 :            :                  */
     426                 :          0 :                 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
     427                 :            : 
     428                 :            :                 /* Add the rest of the snow IV to the context */
     429                 :          0 :                 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
     430                 :            :         }
     431                 :            : 
     432                 :            :         /* Set the variable size of data the register will write */
     433         [ #  # ]:          0 :         if (dir == OP_TYPE_ENCAP_PROTOCOL) {
     434                 :            :                 /* We will add the integrity data so add its length */
     435                 :          0 :                 MATHI(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
     436                 :            :         } else {
     437                 :            :                 /* We will check the integrity data so remove its length */
     438                 :          0 :                 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
     439                 :            :                 /* Do not take the ICV in the out-snooping configuration */
     440                 :          0 :                 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4, IMMED2);
     441                 :            :         }
     442                 :            : 
     443                 :            :         /* We write the PDCP header to output*/
     444                 :          0 :         SEQSTORE(p, MATH0, offset, length, 0);
     445                 :            : 
     446                 :            :         /* Definition of the flow of output data */
     447         [ #  # ]:          0 :         if (dir == OP_TYPE_ENCAP_PROTOCOL) {
     448                 :            :                 /* We write data according to VSEQOUTSZ */
     449                 :          0 :                 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
     450                 :            :         } else {
     451                 :            :                 /* We write data according to VSEQOUTSZ */
     452                 :          0 :                 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
     453                 :            :         }
     454                 :            : 
     455                 :            :         /* Get parameters for authentication */
     456         [ #  # ]:          0 :         if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) {
     457                 :            :                 int_op_alg = OP_ALG_ALGSEL_ZUCA;
     458                 :            :                 int_op_aai = OP_ALG_AAI_F9;
     459         [ #  # ]:          0 :         } else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) {
     460                 :            :                 int_op_alg = OP_ALG_ALGSEL_SNOW_F9;
     461                 :            :                 int_op_aai = OP_ALG_AAI_F9;
     462                 :            :         } else {
     463                 :          0 :                 pr_err("%s no support for auth alg: %d\n", __func__,
     464                 :            :                        authdata->algtype);
     465                 :          0 :                 return -1;
     466                 :            :         }
     467                 :            : 
     468                 :            :         /* Get parameters for ciphering */
     469         [ #  # ]:          0 :         if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
     470                 :            :                 cipher_op_alg = OP_ALG_ALGSEL_ZUCE;
     471                 :            :                 cipher_op_aai = OP_ALG_AAI_F8;
     472         [ #  # ]:          0 :         } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
     473                 :            :                 cipher_op_alg = OP_ALG_ALGSEL_SNOW_F8;
     474                 :            :                 cipher_op_aai = OP_ALG_AAI_F8;
     475         [ #  # ]:          0 :         } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
     476                 :            :                 cipher_op_alg = OP_ALG_ALGSEL_AES;
     477                 :            :                 cipher_op_aai = OP_ALG_AAI_CTR;
     478                 :            :         } else {
     479                 :          0 :                 pr_err("%s no support for cipher alg: %d\n", __func__,
     480                 :            :                        authdata->algtype);
     481                 :          0 :                 return -1;
     482                 :            :         }
     483                 :            : 
     484                 :            :         /* Configure the CHA, the class 2 CHA must be configured first or an
     485                 :            :          * error will be generated
     486                 :            :          */
     487                 :            : 
     488                 :            :         /* Configure the class 2 CHA (integrity )*/
     489                 :          0 :         ALG_OPERATION(p, int_op_alg, int_op_aai, OP_ALG_AS_INITFINAL,
     490                 :            :                       dir == OP_TYPE_ENCAP_PROTOCOL ? ICV_CHECK_DISABLE :
     491                 :            :                                                       ICV_CHECK_ENABLE,
     492                 :            :                       DIR_ENC);
     493                 :            : 
     494                 :            :         /* Configure class 1 CHA (confidentiality)*/
     495                 :          0 :         ALG_OPERATION(p, cipher_op_alg, cipher_op_aai, OP_ALG_AS_INITFINAL,
     496                 :            :                       ICV_CHECK_DISABLE,
     497                 :            :                       dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
     498                 :            : 
     499                 :            :         /* Definition of the flow of input data */
     500         [ #  # ]:          0 :         if (dir == OP_TYPE_ENCAP_PROTOCOL) {
     501                 :            :                 /* We read data according to VSEQINSZ
     502                 :            :                  * Note: we perform an in-snooping, eg the data will be read
     503                 :            :                  * only once. they will be sent to both the integrity CHA and
     504                 :            :                  * confidentiality CHA
     505                 :            :                  */
     506                 :          0 :                 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
     507                 :            : 
     508                 :            :                 /* When the integrity CHA is finished, send the ICV stored in
     509                 :            :                  * the context to the confidentiality CHA for encryption
     510                 :            :                  */
     511                 :          0 :                 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
     512                 :            :         } else {
     513                 :            :                 /* We read data according to VSEQINSZ
     514                 :            :                  * Note: we perform an out-snooping, eg the data will be read
     515                 :            :                  * only once. The will first be sent to the confidentiality
     516                 :            :                  * CHA for decryption, then the CAAM will direct them to the
     517                 :            :                  * integrity CHA to verify the ICV (which is at the end of the
     518                 :            :                  * sequence)
     519                 :            :                  */
     520                 :          0 :                 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
     521                 :            : 
     522                 :            :                 /* Process the ICV by class 1 CHA */
     523                 :          0 :                 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
     524                 :            : 
     525                 :            :                 /* Wait for class 1 CHA to finish, the ICV data are stalling in
     526                 :            :                  * the output fifo
     527                 :            :                  */
     528                 :          0 :                 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
     529                 :            : 
     530                 :          0 :                 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
     531                 :            : 
     532                 :            :                 /* Save the content left in the Output FIFO (the ICV) to MATH0
     533                 :            :                  */
     534                 :          0 :                 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
     535                 :            : 
     536                 :            :                 /* Configure a NFIFO entry to take data from the altsource
     537                 :            :                  * and send it to the class 2 CHA as an ICV
     538                 :            :                  */
     539                 :          0 :                 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
     540                 :            : 
     541                 :            :                 /* Move the content of MATH0 (OFIFO offset) to altsource
     542                 :            :                  * Note: As configured by the altsource, this will send
     543                 :            :                  * the
     544                 :            :                  */
     545                 :          0 :                 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
     546                 :            :         }
     547                 :            : 
     548         [ #  # ]:          0 :         if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
     549                 :            :                 /* Reset ZUCA mode and done interrupt
     550                 :            :                  * Note: If it is not done, DECO generate an error: 200031ca
     551                 :            :                  * -> ZUCA ICV failed
     552                 :            :                  */
     553                 :          0 :                 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
     554                 :          0 :                 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
     555                 :            :         }
     556                 :            : 
     557                 :            :         return 0;
     558                 :            : }
     559                 :            : 
     560                 :            : /* Function used when the integrity algorithm is a class 1 CHA so outsnooping
     561                 :            :  * is not possible
     562                 :            :  * Supported:
     563                 :            :  *  - cipher:
     564                 :            :  *      - AES-CTR
     565                 :            :  *      - SNOW F8
     566                 :            :  *      - ZUC F8
     567                 :            :  *  - authentication
     568                 :            :  *      - AES-CMAC
     569                 :            :  */
     570                 :          0 : static inline int pdcp_sdap_insert_no_snoop_op(
     571                 :            :         struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata,
     572                 :            :         struct alginfo *authdata, unsigned int dir, enum pdcp_sn_size sn_size,
     573                 :            :         enum pdb_type_e pdb_type)
     574                 :            : {
     575                 :          0 :         uint32_t offset = 0, length = 0, sn_mask = 0;
     576                 :            :         uint32_t cipher_alg_op = 0;
     577                 :            :         uint32_t cipher_alg_aai = 0;
     578                 :            :         int hfn_bearer_dir_offset_in_descbuf =
     579                 :            :                 (pdb_type == PDCP_PDB_TYPE_FULL_PDB) ?
     580         [ #  # ]:          0 :                         FULL_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET :
     581                 :            :                         REDUCED_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET;
     582                 :            : 
     583         [ #  # ]:          0 :         if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
     584                 :            :                                         &sn_mask))
     585                 :            :                 return -ENOTSUP;
     586                 :            : 
     587                 :          0 :         SEQLOAD(p, MATH0, offset, length, 0);
     588                 :          0 :         JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
     589                 :            : 
     590                 :            : #ifdef SDAP_SUPPORT
     591         [ #  # ]:          0 :         rta_mathi(p, MATH0,
     592                 :            :                   ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
     593                 :            :                   SDAP_BITS_SIZE, MATH1, 8, 0);
     594                 :          0 :         MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     595                 :            : #else
     596                 :            :         MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
     597                 :            : #endif
     598                 :            : 
     599                 :          0 :         MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
     600                 :          0 :         MOVEB(p, DESCBUF, hfn_bearer_dir_offset_in_descbuf,
     601                 :            :                         MATH2, 0, 0x08, WAITCOMP | IMMED);
     602                 :          0 :         MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
     603                 :            : 
     604                 :          0 :         SEQSTORE(p, MATH0, offset, length, 0);
     605                 :            : 
     606         [ #  # ]:          0 :         if (dir == OP_TYPE_ENCAP_PROTOCOL) {
     607                 :            :                 /* Load authentication key */
     608                 :          0 :                 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
     609                 :            :                     authdata->keylen, INLINE_KEY(authdata));
     610                 :            : 
     611                 :            :                 /* Set the iv for AES authentication */
     612                 :          0 :                 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
     613                 :            : 
     614                 :            :                 /* Pass the header */
     615                 :          0 :                 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
     616                 :            : 
     617                 :            :                 /* Configure variable size for I/O */
     618                 :          0 :                 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
     619                 :          0 :                 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
     620                 :            : 
     621                 :            :                 /* Perform the authentication */
     622                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC,
     623                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC);
     624                 :            : 
     625                 :            :                 /* Configure the read of data */
     626                 :          0 :                 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
     627                 :            : 
     628                 :            :                 /* Save the ICV generated */
     629                 :          0 :                 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
     630                 :            : 
     631                 :            :                 /* conditional jump with calm added to ensure that the
     632                 :            :                  * previous processing has been completed
     633                 :            :                  */
     634                 :          0 :                 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
     635                 :            :                 /* The CHA will be reused so we need to clear it */
     636                 :          0 :                 LOAD(p, CLRW_RESET_CLS1_CHA |
     637                 :            :                      CLRW_CLR_C1KEY |
     638                 :            :                      CLRW_CLR_C1CTX |
     639                 :            :                      CLRW_CLR_C1ICV |
     640                 :            :                      CLRW_CLR_C1DATAS |
     641                 :            :                      CLRW_CLR_C1MODE,
     642                 :            :                      CLRW, 0, 4, IMMED);
     643                 :            : 
     644                 :            :                 /* Load confidentiality key */
     645                 :          0 :                 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
     646                 :            :                     cipherdata->keylen, INLINE_KEY(cipherdata));
     647                 :            : 
     648                 :            :                 /* Load the IV for ciphering */
     649         [ #  # ]:          0 :                 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
     650                 :          0 :                         MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
     651                 :            :                         cipher_alg_op = OP_ALG_ALGSEL_AES;
     652                 :            :                         cipher_alg_aai = OP_ALG_AAI_CTR;
     653         [ #  # ]:          0 :                 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
     654                 :            :                         /* Set the IV for the confidentiality CHA */
     655                 :          0 :                         MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
     656                 :            :                         cipher_alg_op = OP_ALG_ALGSEL_ZUCE;
     657                 :            :                         cipher_alg_aai = OP_ALG_AAI_F8;
     658         [ #  # ]:          0 :                 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
     659                 :            :                         /* Set the IV for the confidentiality CHA */
     660                 :          0 :                         MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
     661                 :            :                         cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8;
     662                 :            :                         cipher_alg_aai = OP_ALG_AAI_F8;
     663                 :            :                 }
     664                 :            : 
     665                 :            :                 /* Rewind the pointer on input data to reread it */
     666                 :          0 :                 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
     667                 :            : 
     668                 :            :                 /* Define the ciphering operation */
     669                 :          0 :                 ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai,
     670                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
     671                 :            : 
     672                 :            :                 /* Define the data to write */
     673                 :          0 :                 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
     674                 :            : 
     675                 :            :                 /* Skip the header which does not need to be encrypted */
     676                 :          0 :                 SEQFIFOLOAD(p, SKIP, length, 0);
     677                 :            : 
     678                 :            :                 /* Read the rest of the data */
     679                 :          0 :                 SEQFIFOLOAD(p, MSG1, 0, VLF);
     680                 :            : 
     681                 :            :                 /* Send the ICV stored in MATH3 for encryption */
     682                 :          0 :                 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
     683                 :            :         } else {
     684                 :            :                 /* Load the IV for ciphering */
     685         [ #  # ]:          0 :                 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
     686                 :          0 :                         MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
     687                 :            :                         cipher_alg_op = OP_ALG_ALGSEL_AES;
     688                 :            :                         cipher_alg_aai = OP_ALG_AAI_CTR;
     689         [ #  # ]:          0 :                 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
     690                 :            :                         /* Set the IV for the confidentiality CHA */
     691                 :          0 :                         MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
     692                 :            :                         cipher_alg_op = OP_ALG_ALGSEL_ZUCE;
     693                 :            :                         cipher_alg_aai = OP_ALG_AAI_F8;
     694         [ #  # ]:          0 :                 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
     695                 :            :                         /* Set the IV for the confidentiality CHA */
     696                 :          0 :                         MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
     697                 :            :                         cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8;
     698                 :            :                         cipher_alg_aai = OP_ALG_AAI_F8;
     699                 :            :                 }
     700                 :          0 :                 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
     701                 :            : 
     702                 :            :                 /* Read all the data */
     703                 :          0 :                 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
     704                 :            : 
     705                 :            :                 /* Do not write back the ICV */
     706                 :          0 :                 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
     707                 :            : 
     708                 :            :                 /* Load the key for ciphering */
     709                 :          0 :                 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
     710                 :            :                     cipherdata->keylen, INLINE_KEY(cipherdata));
     711                 :            : 
     712                 :            :                 /* Write all the data */
     713                 :          0 :                 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
     714                 :            : 
     715                 :            :                 /* Define the ciphering algorithm */
     716                 :          0 :                 ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai,
     717                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC);
     718                 :            : 
     719                 :            :                 /* Read all the data */
     720                 :          0 :                 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
     721                 :            : 
     722                 :            :                 /* Save the ICV which is stalling in output FIFO to MATH3 */
     723                 :          0 :                 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
     724                 :            : 
     725                 :            :                 /* conditional jump with calm added to ensure that the
     726                 :            :                  * previous processing has been completed
     727                 :            :                  */
     728                 :          0 :                 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
     729                 :            :                 /* Reset class 1 CHA */
     730                 :          0 :                 LOAD(p, CLRW_RESET_CLS1_CHA |
     731                 :            :                      CLRW_CLR_C1KEY |
     732                 :            :                      CLRW_CLR_C1CTX |
     733                 :            :                      CLRW_CLR_C1ICV |
     734                 :            :                      CLRW_CLR_C1DATAS |
     735                 :            :                      CLRW_CLR_C1MODE,
     736                 :            :                      CLRW, 0, 4, IMMED);
     737                 :            : 
     738                 :            :                 /* Load the key for authentication */
     739                 :          0 :                 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
     740                 :            :                     authdata->keylen, INLINE_KEY(authdata));
     741                 :            : 
     742                 :            :                 /* Start a new sequence */
     743                 :          0 :                 SEQINPTR(p, 0, 0, SOP);
     744                 :            : 
     745                 :            :                 /* Define the operation to verify the ICV */
     746                 :          0 :                 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC,
     747                 :            :                               OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
     748                 :            : 
     749                 :            :                 /* Set the variable size input */
     750                 :          0 :                 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
     751                 :            : 
     752                 :          0 :                 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
     753                 :            : 
     754                 :          0 :                 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
     755                 :            : 
     756                 :            :                 /* Define an NFIFO entry to load the ICV saved */
     757                 :          0 :                 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
     758                 :            :                      NFIFOENTRY_DEST_CLASS1 |
     759                 :            :                      NFIFOENTRY_DTYPE_ICV |
     760                 :            :                      NFIFOENTRY_LC1 |
     761                 :            :                      NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
     762                 :            : 
     763                 :            :                 /* Load the ICV */
     764                 :          0 :                 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
     765                 :            :         }
     766                 :            : 
     767                 :            :         return 0;
     768                 :            : }
     769                 :            : 
     770                 :            : static inline int
     771                 :          0 : pdcp_sdap_insert_cplane_null_op(struct program *p,
     772                 :            :                            bool swap __maybe_unused,
     773                 :            :                            struct alginfo *cipherdata,
     774                 :            :                            struct alginfo *authdata,
     775                 :            :                            unsigned int dir,
     776                 :            :                            enum pdcp_sn_size sn_size,
     777                 :            :                            enum pdb_type_e pdb_type __maybe_unused)
     778                 :            : {
     779                 :          0 :         return pdcp_insert_cplane_null_op(p, swap, cipherdata, authdata, dir,
     780                 :            :                                           sn_size);
     781                 :            : }
     782                 :            : 
     783                 :            : static inline int
     784                 :          0 : pdcp_sdap_insert_cplane_int_only_op(struct program *p,
     785                 :            :                            bool swap __maybe_unused,
     786                 :            :                            struct alginfo *cipherdata,
     787                 :            :                            struct alginfo *authdata,
     788                 :            :                            unsigned int dir,
     789                 :            :                            enum pdcp_sn_size sn_size,
     790                 :            :                            enum pdb_type_e pdb_type __maybe_unused)
     791                 :            : {
     792                 :          0 :         return pdcp_insert_cplane_int_only_op(p, swap, cipherdata, authdata,
     793                 :            :                                 dir, sn_size);
     794                 :            : }
     795                 :            : 
     796                 :            : static int pdcp_sdap_insert_with_int_op(
     797                 :            :         struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata,
     798                 :            :         struct alginfo *authdata, enum pdcp_sn_size sn_size,
     799                 :            :         unsigned int dir,
     800                 :            :         enum pdb_type_e pdb_type)
     801                 :            : {
     802                 :            :         static int (
     803                 :            :                 *pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])(
     804                 :            :                 struct program *, bool swap, struct alginfo *, struct alginfo *,
     805                 :            :                 unsigned int dir, enum pdcp_sn_size, enum pdb_type_e pdb_type) = {
     806                 :            :                 {
     807                 :            :                         /* NULL */
     808                 :            :                         pdcp_sdap_insert_cplane_null_op,     /* NULL */
     809                 :            :                         pdcp_sdap_insert_cplane_int_only_op, /* SNOW f9 */
     810                 :            :                         pdcp_sdap_insert_cplane_int_only_op, /* AES CMAC */
     811                 :            :                         pdcp_sdap_insert_cplane_int_only_op  /* ZUC-I */
     812                 :            :                 },
     813                 :            :                 {
     814                 :            :                         /* SNOW f8 */
     815                 :            :                         pdcp_sdap_insert_enc_only_op, /* NULL */
     816                 :            :                         pdcp_sdap_insert_snoop_op,    /* SNOW f9 */
     817                 :            :                         pdcp_sdap_insert_no_snoop_op, /* AES CMAC */
     818                 :            :                         pdcp_sdap_insert_snoop_op     /* ZUC-I */
     819                 :            :                 },
     820                 :            :                 {
     821                 :            :                         /* AES CTR */
     822                 :            :                         pdcp_sdap_insert_enc_only_op, /* NULL */
     823                 :            :                         pdcp_sdap_insert_snoop_op,    /* SNOW f9 */
     824                 :            :                         pdcp_sdap_insert_no_snoop_op, /* AES CMAC */
     825                 :            :                         pdcp_sdap_insert_snoop_op     /* ZUC-I */
     826                 :            :                 },
     827                 :            :                 {
     828                 :            :                         /* ZUC-E */
     829                 :            :                         pdcp_sdap_insert_enc_only_op, /* NULL */
     830                 :            :                         pdcp_sdap_insert_snoop_op,    /* SNOW f9 */
     831                 :            :                         pdcp_sdap_insert_no_snoop_op, /* AES CMAC */
     832                 :            :                         pdcp_sdap_insert_snoop_op     /* ZUC-I */
     833                 :            :                 },
     834                 :            :         };
     835                 :            :         int err;
     836                 :            : 
     837                 :          0 :         err = pdcp_cp_fp[cipherdata->algtype]
     838                 :          0 :                         [authdata->algtype](p, swap, cipherdata, authdata, dir,
     839                 :            :                                         sn_size, pdb_type);
     840         [ #  # ]:          0 :         if (err)
     841                 :            :                 return err;
     842                 :            : 
     843                 :            :         return 0;
     844                 :            : }
     845                 :            : 
     846                 :            : static inline int
     847                 :          0 : cnstr_shdsc_pdcp_sdap_u_plane(uint32_t *descbuf,
     848                 :            :                                bool ps,
     849                 :            :                                bool swap,
     850                 :            :                                enum pdcp_sn_size sn_size,
     851                 :            :                                uint32_t hfn,
     852                 :            :                                unsigned short bearer,
     853                 :            :                                unsigned short direction,
     854                 :            :                                uint32_t hfn_threshold,
     855                 :            :                                struct alginfo *cipherdata,
     856                 :            :                                struct alginfo *authdata,
     857                 :            :                                uint32_t caps_mode)
     858                 :            : {
     859                 :            :         struct program prg;
     860                 :            :         struct program *p = &prg;
     861                 :            :         int err;
     862                 :            :         enum pdb_type_e pdb_type;
     863                 :            :         static enum rta_share_type
     864                 :            :                 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
     865                 :            :                         {
     866                 :            :                                 /* NULL */
     867                 :            :                                 SHR_WAIT,   /* NULL */
     868                 :            :                                 SHR_WAIT, /* SNOW f9 */
     869                 :            :                                 SHR_WAIT, /* AES CMAC */
     870                 :            :                                 SHR_WAIT  /* ZUC-I */
     871                 :            :                         },
     872                 :            :                         {
     873                 :            :                                 /* SNOW f8 */
     874                 :            :                                 SHR_WAIT, /* NULL */
     875                 :            :                                 SHR_WAIT, /* SNOW f9 */
     876                 :            :                                 SHR_WAIT,   /* AES CMAC */
     877                 :            :                                 SHR_WAIT    /* ZUC-I */
     878                 :            :                         },
     879                 :            :                         {
     880                 :            :                                 /* AES CTR */
     881                 :            :                                 SHR_WAIT, /* NULL */
     882                 :            :                                 SHR_WAIT, /* SNOW f9 */
     883                 :            :                                 SHR_WAIT, /* AES CMAC */
     884                 :            :                                 SHR_WAIT    /* ZUC-I */
     885                 :            :                         },
     886                 :            :                         {
     887                 :            :                                 /* ZUC-E */
     888                 :            :                                 SHR_WAIT, /* NULL */
     889                 :            :                                 SHR_WAIT,   /* SNOW f9 */
     890                 :            :                                 SHR_WAIT,   /* AES CMAC */
     891                 :            :                                 SHR_WAIT    /* ZUC-I */
     892                 :            :                         },
     893                 :            :                 };
     894                 :            : 
     895                 :            :         LABEL(pdb_end);
     896                 :            : 
     897                 :            :         /* Check the confidentiality algorithm is supported by the code */
     898         [ #  # ]:          0 :         switch (cipherdata->algtype) {
     899                 :            :         case PDCP_CIPHER_TYPE_NULL:
     900                 :            :         case PDCP_CIPHER_TYPE_SNOW:
     901                 :            :         case PDCP_CIPHER_TYPE_AES:
     902                 :            :         case PDCP_CIPHER_TYPE_ZUC:
     903                 :            :                 break;
     904                 :          0 :         default:
     905                 :          0 :                 pr_err("Cipher algorithm not supported: %d\n",
     906                 :            :                                 cipherdata->algtype);
     907                 :          0 :                 return -ENOTSUP;
     908                 :            :         }
     909                 :            : 
     910                 :            :         /* Check the authentication algorithm is supported by the code */
     911         [ #  # ]:          0 :         if (authdata) {
     912         [ #  # ]:          0 :                 switch (authdata->algtype) {
     913                 :            :                 case PDCP_AUTH_TYPE_NULL:
     914                 :            :                 case PDCP_AUTH_TYPE_SNOW:
     915                 :            :                 case PDCP_AUTH_TYPE_AES:
     916                 :            :                 case PDCP_AUTH_TYPE_ZUC:
     917                 :            :                         break;
     918                 :          0 :                 default:
     919                 :          0 :                         pr_err("Auth algorithm not supported: %d\n",
     920                 :            :                                         authdata->algtype);
     921                 :          0 :                         return -ENOTSUP;
     922                 :            :                 }
     923                 :            :         }
     924                 :            : 
     925                 :            :         /* Check the Sequence Number size is supported by the code */
     926         [ #  # ]:          0 :         switch (sn_size) {
     927                 :            :         case PDCP_SN_SIZE_5:
     928                 :            :         case PDCP_SN_SIZE_7:
     929                 :            :         case PDCP_SN_SIZE_12:
     930                 :            :         case PDCP_SN_SIZE_15:
     931                 :            :         case PDCP_SN_SIZE_18:
     932                 :            :                 break;
     933                 :          0 :         default:
     934                 :          0 :                 pr_err("SN size not supported: %d\n", sn_size);
     935                 :          0 :                 return -ENOTSUP;
     936                 :            :         }
     937                 :            : 
     938                 :            :         /* Initialize the program */
     939                 :            :         PROGRAM_CNTXT_INIT(p, descbuf, 0);
     940                 :            : 
     941         [ #  # ]:          0 :         if (swap)
     942                 :            :                 PROGRAM_SET_BSWAP(p);
     943                 :            : 
     944         [ #  # ]:          0 :         if (ps)
     945                 :            :                 PROGRAM_SET_36BIT_ADDR(p);
     946                 :            : 
     947                 :            :         /* Select the shared descriptor sharing mode */
     948         [ #  # ]:          0 :         if (authdata)
     949                 :          0 :                 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype],
     950                 :            :                         0, 0);
     951                 :            :         else
     952                 :          0 :                 SHR_HDR(p, SHR_WAIT, 0, 0);
     953                 :            : 
     954                 :            :         /* Construct the PDB */
     955                 :          0 :         pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn, bearer, direction,
     956                 :            :                                           hfn_threshold, cipherdata, authdata);
     957         [ #  # ]:          0 :         if (pdb_type == PDCP_PDB_TYPE_INVALID) {
     958                 :          0 :                 pr_err("Error creating PDCP UPlane PDB\n");
     959                 :          0 :                 return -EINVAL;
     960                 :            :         }
     961                 :            :         SET_LABEL(p, pdb_end);
     962                 :            : 
     963                 :            :         /* Inser the HFN override operation */
     964                 :          0 :         err = insert_hfn_ov_op(p, sn_size, pdb_type, false);
     965         [ #  # ]:          0 :         if (err)
     966                 :            :                 return err;
     967                 :            : 
     968                 :            :         /* Create the descriptor */
     969         [ #  # ]:          0 :         if (!authdata) {
     970         [ #  # ]:          0 :                 if (cipherdata->algtype == PDCP_CIPHER_TYPE_NULL) {
     971                 :          0 :                         insert_copy_frame_op(p, cipherdata,
     972                 :            :                                              OP_TYPE_ENCAP_PROTOCOL);
     973                 :            :                 } else {
     974                 :          0 :                         err = pdcp_sdap_insert_no_int_op(p, swap, cipherdata,
     975                 :            :                                                          caps_mode,
     976                 :            :                                                          sn_size, pdb_type);
     977         [ #  # ]:          0 :                         if (err) {
     978                 :          0 :                                 pr_err("Fail pdcp_sdap_insert_no_int_op\n");
     979                 :          0 :                                 return err;
     980                 :            :                         }
     981                 :            :                 }
     982                 :            :         } else {
     983                 :          0 :                 err = pdcp_sdap_insert_with_int_op(p, swap, cipherdata,
     984                 :            :                                                    authdata, sn_size,
     985                 :            :                                                    caps_mode, pdb_type);
     986                 :            :                 if (err) {
     987                 :          0 :                         pr_err("Fail pdcp_sdap_insert_with_int_op\n");
     988                 :          0 :                         return err;
     989                 :            :                 }
     990                 :            :         }
     991                 :            : 
     992                 :          0 :         PATCH_HDR(p, 0, pdb_end);
     993                 :            : 
     994                 :          0 :         return PROGRAM_FINALIZE(p);
     995                 :            : }
     996                 :            : 
     997                 :            : /**
     998                 :            :  * cnstr_shdsc_pdcp_sdap_u_plane_encap - Function for creating a PDCP-SDAP
     999                 :            :  *                                       User Plane encapsulation descriptor.
    1000                 :            :  * @descbuf: pointer to buffer for descriptor construction
    1001                 :            :  * @ps: if 36/40bit addressing is desired, this parameter must be true
    1002                 :            :  * @swap: must be true when core endianness doesn't match SEC endianness
    1003                 :            :  * @sn_size: selects Sequence Number Size: 7/12/15 bits
    1004                 :            :  * @hfn: starting Hyper Frame Number to be used together with the SN from the
    1005                 :            :  *       PDCP frames.
    1006                 :            :  * @bearer: radio bearer ID
    1007                 :            :  * @direction: the direction of the PDCP frame (UL/DL)
    1008                 :            :  * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
    1009                 :            :  *                 keys should be renegotiated at the earliest convenience.
    1010                 :            :  * @cipherdata: pointer to block cipher transform definitions
    1011                 :            :  *              Valid algorithm values are those from cipher_type_pdcp enum.
    1012                 :            :  *
    1013                 :            :  * Return: size of descriptor written in words or negative number on error.
    1014                 :            :  *         Once the function returns, the value of this parameter can be used
    1015                 :            :  *         for reclaiming the space that wasn't used for the descriptor.
    1016                 :            :  *
    1017                 :            :  * Note: descbuf must be large enough to contain a full 256 byte long
    1018                 :            :  * descriptor; after the function returns, by subtracting the actual number of
    1019                 :            :  * bytes used, the user can reuse the remaining buffer space for other purposes.
    1020                 :            :  */
    1021                 :            : static inline int
    1022                 :            : cnstr_shdsc_pdcp_sdap_u_plane_encap(uint32_t *descbuf,
    1023                 :            :                                bool ps,
    1024                 :            :                                bool swap,
    1025                 :            :                                enum pdcp_sn_size sn_size,
    1026                 :            :                                uint32_t hfn,
    1027                 :            :                                unsigned short bearer,
    1028                 :            :                                unsigned short direction,
    1029                 :            :                                uint32_t hfn_threshold,
    1030                 :            :                                struct alginfo *cipherdata,
    1031                 :            :                                struct alginfo *authdata)
    1032                 :            : {
    1033                 :          0 :         return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size,
    1034                 :            :                         hfn, bearer, direction, hfn_threshold, cipherdata,
    1035                 :            :                         authdata, OP_TYPE_ENCAP_PROTOCOL);
    1036                 :            : }
    1037                 :            : 
    1038                 :            : /**
    1039                 :            :  * cnstr_shdsc_pdcp_sdap_u_plane_decap - Function for creating a PDCP-SDAP
    1040                 :            :  *                                       User Plane decapsulation descriptor.
    1041                 :            :  * @descbuf: pointer to buffer for descriptor construction
    1042                 :            :  * @ps: if 36/40bit addressing is desired, this parameter must be true
    1043                 :            :  * @swap: must be true when core endianness doesn't match SEC endianness
    1044                 :            :  * @sn_size: selects Sequence Number Size: 7/12/15 bits
    1045                 :            :  * @hfn: starting Hyper Frame Number to be used together with the SN from the
    1046                 :            :  *       PDCP frames.
    1047                 :            :  * @bearer: radio bearer ID
    1048                 :            :  * @direction: the direction of the PDCP frame (UL/DL)
    1049                 :            :  * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
    1050                 :            :  *                 keys should be renegotiated at the earliest convenience.
    1051                 :            :  * @cipherdata: pointer to block cipher transform definitions
    1052                 :            :  *              Valid algorithm values are those from cipher_type_pdcp enum.
    1053                 :            :  *
    1054                 :            :  * Return: size of descriptor written in words or negative number on error.
    1055                 :            :  *         Once the function returns, the value of this parameter can be used
    1056                 :            :  *         for reclaiming the space that wasn't used for the descriptor.
    1057                 :            :  *
    1058                 :            :  * Note: descbuf must be large enough to contain a full 256 byte long
    1059                 :            :  * descriptor; after the function returns, by subtracting the actual number of
    1060                 :            :  * bytes used, the user can reuse the remaining buffer space for other purposes.
    1061                 :            :  */
    1062                 :            : static inline int
    1063                 :            : cnstr_shdsc_pdcp_sdap_u_plane_decap(uint32_t *descbuf,
    1064                 :            :                                bool ps,
    1065                 :            :                                bool swap,
    1066                 :            :                                enum pdcp_sn_size sn_size,
    1067                 :            :                                uint32_t hfn,
    1068                 :            :                                unsigned short bearer,
    1069                 :            :                                unsigned short direction,
    1070                 :            :                                uint32_t hfn_threshold,
    1071                 :            :                                struct alginfo *cipherdata,
    1072                 :            :                                struct alginfo *authdata)
    1073                 :            : {
    1074                 :          0 :         return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size, hfn,
    1075                 :            :                         bearer, direction, hfn_threshold, cipherdata, authdata,
    1076                 :            :                         OP_TYPE_DECAP_PROTOCOL);
    1077                 :            : }
    1078                 :            : 
    1079                 :            : #endif /* __DESC_SDAP_H__ */

Generated by: LCOV version 1.14