(root)/
strace-6.5/
src/
netlink_crypto.c
       1  /*
       2   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       3   * Copyright (c) 2017-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: LGPL-2.1-or-later
       7   */
       8  
       9  #include "defs.h"
      10  
      11  #include "netlink.h"
      12  #include "nlattr.h"
      13  
      14  #include <linux/cryptouser.h>
      15  
      16  #include "xlat/crypto_nl_attrs.h"
      17  
      18  
      19  static bool
      20  decode_crypto_report_generic(struct tcb *const tcp,
      21  			     const kernel_ulong_t addr,
      22  			     const unsigned int len,
      23  			     const void *const opaque_data)
      24  {
      25  	tprint_struct_begin();
      26  	tprints_field_name("type");
      27  	printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
      28  	tprint_struct_end();
      29  
      30  	return true;
      31  }
      32  
      33  static bool
      34  decode_crypto_report_hash(struct tcb *const tcp,
      35  			  const kernel_ulong_t addr,
      36  			  const unsigned int len,
      37  			  const void *const opaque_data)
      38  {
      39  	struct crypto_report_hash rhash;
      40  
      41  	if (len < sizeof(rhash))
      42  		printstrn(tcp, addr, len);
      43  	else if (!umove_or_printaddr(tcp, addr, &rhash)) {
      44  		tprint_struct_begin();
      45  		PRINT_FIELD_CSTRING(rhash, type);
      46  		tprint_struct_next();
      47  		PRINT_FIELD_U(rhash, blocksize);
      48  		tprint_struct_next();
      49  		PRINT_FIELD_U(rhash, digestsize);
      50  		tprint_struct_end();
      51  	}
      52  
      53  	return true;
      54  }
      55  
      56  static bool
      57  decode_crypto_report_blkcipher(struct tcb *const tcp,
      58  			       const kernel_ulong_t addr,
      59  			       const unsigned int len,
      60  			       const void *const opaque_data)
      61  {
      62  	struct crypto_report_blkcipher rblkcipher;
      63  
      64  	if (len < sizeof(rblkcipher))
      65  		printstrn(tcp, addr, len);
      66  	else if (!umove_or_printaddr(tcp, addr, &rblkcipher)) {
      67  		tprint_struct_begin();
      68  		PRINT_FIELD_CSTRING(rblkcipher, type);
      69  		tprint_struct_next();
      70  		PRINT_FIELD_CSTRING(rblkcipher, geniv);
      71  		tprint_struct_next();
      72  		PRINT_FIELD_U(rblkcipher, blocksize);
      73  		tprint_struct_next();
      74  		PRINT_FIELD_U(rblkcipher, min_keysize);
      75  		tprint_struct_next();
      76  		PRINT_FIELD_U(rblkcipher, max_keysize);
      77  		tprint_struct_next();
      78  		PRINT_FIELD_U(rblkcipher, ivsize);
      79  		tprint_struct_end();
      80  	}
      81  
      82  	return true;
      83  }
      84  
      85  static bool
      86  decode_crypto_report_aead(struct tcb *const tcp,
      87  			  const kernel_ulong_t addr,
      88  			  const unsigned int len,
      89  			  const void *const opaque_data)
      90  {
      91  	struct crypto_report_aead raead;
      92  
      93  	if (len < sizeof(raead))
      94  		printstrn(tcp, addr, len);
      95  	else if (!umove_or_printaddr(tcp, addr, &raead)) {
      96  		tprint_struct_begin();
      97  		PRINT_FIELD_CSTRING(raead, type);
      98  		tprint_struct_next();
      99  		PRINT_FIELD_CSTRING(raead, geniv);
     100  		tprint_struct_next();
     101  		PRINT_FIELD_U(raead, blocksize);
     102  		tprint_struct_next();
     103  		PRINT_FIELD_U(raead, maxauthsize);
     104  		tprint_struct_next();
     105  		PRINT_FIELD_U(raead, ivsize);
     106  		tprint_struct_end();
     107  	}
     108  
     109  	return true;
     110  }
     111  
     112  static bool
     113  decode_crypto_report_rng(struct tcb *const tcp,
     114  			 const kernel_ulong_t addr,
     115  			 const unsigned int len,
     116  			 const void *const opaque_data)
     117  {
     118  	struct crypto_report_rng rrng;
     119  
     120  	if (len < sizeof(rrng))
     121  		printstrn(tcp, addr, len);
     122  	else if (!umove_or_printaddr(tcp, addr, &rrng)) {
     123  		tprint_struct_begin();
     124  		PRINT_FIELD_CSTRING(rrng, type);
     125  		tprint_struct_next();
     126  		PRINT_FIELD_U(rrng, seedsize);
     127  		tprint_struct_end();
     128  	}
     129  
     130  	return true;
     131  }
     132  
     133  static bool
     134  decode_crypto_report_cipher(struct tcb *const tcp,
     135  			    const kernel_ulong_t addr,
     136  			    const unsigned int len,
     137  			    const void *const opaque_data)
     138  {
     139  	struct crypto_report_cipher rcipher;
     140  
     141  	if (len < sizeof(rcipher))
     142  		printstrn(tcp, addr, len);
     143  	else if (!umove_or_printaddr(tcp, addr, &rcipher)) {
     144  		tprint_struct_begin();
     145  		PRINT_FIELD_CSTRING(rcipher, type);
     146  		tprint_struct_next();
     147  		PRINT_FIELD_U(rcipher, blocksize);
     148  		tprint_struct_next();
     149  		PRINT_FIELD_U(rcipher, min_keysize);
     150  		tprint_struct_next();
     151  		PRINT_FIELD_U(rcipher, max_keysize);
     152  		tprint_struct_end();
     153  	}
     154  
     155  	return true;
     156  }
     157  
     158  static const nla_decoder_t crypto_user_alg_nla_decoders[] = {
     159  	[CRYPTOCFGA_PRIORITY_VAL]	= decode_nla_u32,
     160  	[CRYPTOCFGA_REPORT_LARVAL]	= decode_crypto_report_generic,
     161  	[CRYPTOCFGA_REPORT_HASH]	= decode_crypto_report_hash,
     162  	[CRYPTOCFGA_REPORT_BLKCIPHER]	= decode_crypto_report_blkcipher,
     163  	[CRYPTOCFGA_REPORT_AEAD]	= decode_crypto_report_aead,
     164  	[CRYPTOCFGA_REPORT_COMPRESS]	= decode_crypto_report_generic,
     165  	[CRYPTOCFGA_REPORT_RNG]		= decode_crypto_report_rng,
     166  	[CRYPTOCFGA_REPORT_CIPHER]	= decode_crypto_report_cipher,
     167  	[CRYPTOCFGA_REPORT_AKCIPHER]	= decode_crypto_report_generic,
     168  	[CRYPTOCFGA_REPORT_KPP]		= decode_crypto_report_generic,
     169  	[CRYPTOCFGA_REPORT_ACOMP]	= decode_crypto_report_generic
     170  };
     171  
     172  static void
     173  decode_crypto_user_alg(struct tcb *const tcp,
     174  		       const kernel_ulong_t addr,
     175  		       const unsigned int len)
     176  {
     177  	struct crypto_user_alg alg;
     178  
     179  	if (len < sizeof(alg))
     180  		printstrn(tcp, addr, len);
     181  	else if (!umove_or_printaddr(tcp, addr, &alg)) {
     182  		tprint_struct_begin();
     183  		PRINT_FIELD_CSTRING(alg, cru_name);
     184  		tprint_struct_next();
     185  		PRINT_FIELD_CSTRING(alg, cru_driver_name);
     186  		tprint_struct_next();
     187  		PRINT_FIELD_CSTRING(alg, cru_module_name);
     188  		tprint_struct_next();
     189  		PRINT_FIELD_X(alg, cru_type);
     190  		tprint_struct_next();
     191  		PRINT_FIELD_X(alg, cru_mask);
     192  		tprint_struct_next();
     193  		PRINT_FIELD_U(alg, cru_refcnt);
     194  		tprint_struct_next();
     195  		PRINT_FIELD_X(alg, cru_flags);
     196  		tprint_struct_end();
     197  
     198  		const size_t offset = NLMSG_ALIGN(sizeof(alg));
     199  		if (len > offset) {
     200  			tprint_array_next();
     201  			decode_nlattr(tcp, addr + offset, len - offset,
     202  				      crypto_nl_attrs, "CRYPTOCFGA_???",
     203  				      crypto_user_alg_nla_decoders,
     204  				      ARRAY_SIZE(crypto_user_alg_nla_decoders),
     205  				      NULL);
     206  		}
     207  	}
     208  }
     209  
     210  bool
     211  decode_netlink_crypto(struct tcb *const tcp,
     212  		      const struct nlmsghdr *const nlmsghdr,
     213  		      const kernel_ulong_t addr,
     214  		      const unsigned int len)
     215  {
     216  	switch (nlmsghdr->nlmsg_type) {
     217  	case CRYPTO_MSG_NEWALG:
     218  	case CRYPTO_MSG_DELALG:
     219  	case CRYPTO_MSG_UPDATEALG:
     220  	case CRYPTO_MSG_GETALG:
     221  		decode_crypto_user_alg(tcp, addr, len);
     222  		break;
     223  	default:
     224  		return false;
     225  	}
     226  
     227  	return true;
     228  }