Advertisement
Guest User

libnl-3 message trunc poc impl

a guest
Jun 3rd, 2015
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.88 KB | None | 0 0
  1. #include <sys/socket.h>
  2. #include <linux/netlink.h>
  3. #include <netlink/netlink.h>
  4. #include <netlink/errno.h>
  5. #include <netlink/socket.h>
  6. #include <netlink/handlers.h>
  7. #include <netlink/msg.h>
  8.  
  9. /* NOTE: inlined cryptouser header from crconf project */
  10. /*
  11.  * Crypto user configuration API.
  12.  *
  13.  * Copyright (C) 2011 secunet Security Networks AG
  14.  * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com>
  15.  *
  16.  * This program is free software; you can redistribute it and/or modify it
  17.  * under the terms and conditions of the GNU General Public License,
  18.  * version 2, as published by the Free Software Foundation.
  19.  *
  20.  * This program is distributed in the hope it will be useful, but WITHOUT
  21.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  22.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  23.  * more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License along with
  26.  * this program; if not, write to the Free Software Foundation, Inc.,
  27.  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  28.  */
  29.  
  30. #include <linux/types.h>
  31.  
  32. #define CRYPTO_MAX_ALG_NAME 64
  33. #define NLMSG_BUF_SIZE 4096
  34.  
  35. /*
  36.  * Algorithm masks and types.
  37.  */
  38. #define CRYPTO_ALG_TYPE_MASK            0x0000000f
  39. #define CRYPTO_ALG_TYPE_CIPHER          0x00000001
  40. #define CRYPTO_ALG_TYPE_COMPRESS        0x00000002
  41. #define CRYPTO_ALG_TYPE_AEAD            0x00000003
  42. #define CRYPTO_ALG_TYPE_BLKCIPHER       0x00000004
  43. #define CRYPTO_ALG_TYPE_ABLKCIPHER      0x00000005
  44. #define CRYPTO_ALG_TYPE_GIVCIPHER       0x00000006
  45. #define CRYPTO_ALG_TYPE_DIGEST          0x00000008
  46. #define CRYPTO_ALG_TYPE_HASH            0x00000008
  47. #define CRYPTO_ALG_TYPE_SHASH           0x00000009
  48. #define CRYPTO_ALG_TYPE_AHASH           0x0000000a
  49. #define CRYPTO_ALG_TYPE_RNG             0x0000000c
  50. #define CRYPTO_ALG_TYPE_PCOMPRESS       0x0000000f
  51.  
  52. #define CRYPTO_ALG_TYPE_HASH_MASK       0x0000000e
  53. #define CRYPTO_ALG_TYPE_AHASH_MASK      0x0000000c
  54. #define CRYPTO_ALG_TYPE_BLKCIPHER_MASK  0x0000000c
  55.  
  56. #define CRYPTO_ALG_LARVAL       0x00000010
  57. #define CRYPTO_ALG_DEAD         0x00000020
  58. #define CRYPTO_ALG_DYING        0x00000040
  59. #define CRYPTO_ALG_ASYNC        0x00000080
  60.  
  61. /*
  62.  * Set this bit if and only if the algorithm requires another algorithm of
  63.  * the same type to handle corner cases.
  64.  */
  65. #define CRYPTO_ALG_NEED_FALLBACK    0x00000100
  66.  
  67. /*
  68.  * This bit is set for symmetric key ciphers that have already been wrapped
  69.  * with a generic IV generator to prevent them from being wrapped again.
  70.  */
  71. #define CRYPTO_ALG_GENIV        0x00000200
  72.  
  73. /*
  74.  * Set if the algorithm has passed automated run-time testing.  Note that
  75.  * if there is no run-time testing for a given algorithm it is considered
  76.  * to have passed.
  77.  */
  78.  
  79. #define CRYPTO_ALG_TESTED       0x00000400
  80.  
  81. /*
  82.  * Set if the algorithm is an instance that is build from telplates.
  83.  */
  84. #define CRYPTO_ALG_INSTANCE     0x00000800
  85.  
  86. /* Netlink configuration messages.  */
  87. enum {
  88.     CRYPTO_MSG_BASE = 0x10,
  89.     CRYPTO_MSG_NEWALG = 0x10,
  90.     CRYPTO_MSG_DELALG,
  91.     CRYPTO_MSG_UPDATEALG,
  92.     CRYPTO_MSG_GETALG,
  93.     __CRYPTO_MSG_MAX
  94. };
  95. #define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1)
  96. #define CRYPTO_NR_MSGTYPES (CRYPTO_MSG_MAX + 1 - CRYPTO_MSG_BASE)
  97.  
  98. /* Netlink message attributes.  */
  99. enum crypto_attr_type_t {
  100.     CRYPTOCFGA_UNSPEC,
  101.     CRYPTOCFGA_PRIORITY_VAL,    /* __u32 */
  102.     CRYPTOCFGA_REPORT_LARVAL,   /* struct crypto_report_larval */
  103.     CRYPTOCFGA_REPORT_HASH,     /* struct crypto_report_hash */
  104.     CRYPTOCFGA_REPORT_BLKCIPHER,    /* struct crypto_report_blkcipher */
  105.     CRYPTOCFGA_REPORT_AEAD,     /* struct crypto_report_aead */
  106.     CRYPTOCFGA_REPORT_COMPRESS, /* struct crypto_report_comp */
  107.     CRYPTOCFGA_REPORT_RNG,      /* struct crypto_report_rng */
  108.     CRYPTOCFGA_REPORT_CIPHER,   /* struct crypto_report_cipher */
  109.     __CRYPTOCFGA_MAX
  110.  
  111. #define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
  112. };
  113.  
  114.  
  115. struct crypto_user_alg {
  116.     char cru_name[CRYPTO_MAX_ALG_NAME];
  117.     char cru_driver_name[CRYPTO_MAX_ALG_NAME];
  118.     char cru_module_name[CRYPTO_MAX_ALG_NAME];
  119.     __u32 cru_type;
  120.     __u32 cru_mask;
  121.     __u32 cru_refcnt;
  122.     __u32 cru_flags;
  123. };
  124.  
  125. #define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
  126.  
  127. struct crypto_report_larval {
  128.     char type[CRYPTO_MAX_NAME];
  129. };
  130.  
  131. struct crypto_report_hash {
  132.     char type[CRYPTO_MAX_NAME];
  133.     unsigned int blocksize;
  134.     unsigned int digestsize;
  135. };
  136.  
  137. struct crypto_report_cipher {
  138.     char type[CRYPTO_MAX_NAME];
  139.     unsigned int blocksize;
  140.     unsigned int min_keysize;
  141.     unsigned int max_keysize;
  142. };
  143.  
  144. struct crypto_report_blkcipher {
  145.     char type[CRYPTO_MAX_NAME];
  146.     char geniv[CRYPTO_MAX_NAME];
  147.     unsigned int blocksize;
  148.     unsigned int min_keysize;
  149.     unsigned int max_keysize;
  150.     unsigned int ivsize;
  151. };
  152.  
  153. struct crypto_report_aead {
  154.     char type[CRYPTO_MAX_NAME];
  155.     char geniv[CRYPTO_MAX_NAME];
  156.     unsigned int blocksize;
  157.     unsigned int maxauthsize;
  158.     unsigned int ivsize;
  159. };
  160.  
  161. struct crypto_report_comp {
  162.     char type[CRYPTO_MAX_NAME];
  163. };
  164.  
  165. struct crypto_report_rng {
  166.     char type[CRYPTO_MAX_NAME];
  167.     unsigned int seedsize;
  168. };
  169.  
  170. #define CR_RTA(x)  ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct crypto_user_alg))))
  171.  
  172. static void log_algo(struct crypto_user_alg *ualg,
  173.         enum crypto_attr_type_t attr_type, void *ptr, unsigned int count)
  174. {
  175.     struct crypto_report_hash *hash;
  176.     struct crypto_report_blkcipher *blkcipher;
  177.     struct crypto_report_aead *aead;
  178.     struct crypto_report_rng *rng;
  179.     struct crypto_report_cipher *cipher;
  180.  
  181.     if (1 != count)
  182.     {
  183.         fprintf(stdout, "===============\n");
  184.     }
  185.     fprintf(stdout, "algorithm #%d\n", count);
  186.     fprintf(stdout, "name:        %s\n", ualg->cru_name);
  187.     fprintf(stdout, "type:        %s\n", (char *)ptr);
  188.  
  189.     switch (attr_type)
  190.     {
  191.         case CRYPTOCFGA_REPORT_HASH:
  192.             hash = (struct crypto_report_hash *)ptr;
  193.             fprintf(stdout, "blocksize:   %d\n", hash->blocksize);
  194.             fprintf(stdout, "digestsize:  %d\n", hash->digestsize);
  195.             break;
  196.         case CRYPTOCFGA_REPORT_BLKCIPHER:
  197.             blkcipher = (struct crypto_report_blkcipher *)ptr;
  198.             fprintf(stdout, "geniv:       %s\n", blkcipher->geniv);
  199.             fprintf(stdout, "blocksize:   %d\n", blkcipher->blocksize);
  200.             fprintf(stdout, "min_keysize: %d\n", blkcipher->min_keysize);
  201.             fprintf(stdout, "max_keysize: %d\n", blkcipher->max_keysize);
  202.             fprintf(stdout, "ivsize:      %d\n", blkcipher->ivsize);
  203.             break;
  204.         case CRYPTOCFGA_REPORT_AEAD:
  205.             aead = (struct crypto_report_aead *)ptr;
  206.             fprintf(stdout, "geniv:       %s\n", aead->geniv);
  207.             fprintf(stdout, "blocksize:   %d\n", aead->blocksize);
  208.             fprintf(stdout, "maxauthsize: %d\n", aead->maxauthsize);
  209.             fprintf(stdout, "ivsize:      %d\n", aead->ivsize);
  210.             break;
  211.         case CRYPTOCFGA_REPORT_RNG:
  212.             rng = (struct crypto_report_rng *)ptr;
  213.             fprintf(stdout, "seedsize:    %d\n", rng->seedsize);
  214.             break;
  215.         case CRYPTOCFGA_REPORT_CIPHER:
  216.             cipher = (struct crypto_report_cipher *)ptr;
  217.             fprintf(stdout, "blocksize:   %d\n", cipher->blocksize);
  218.             fprintf(stdout, "min_keysize: %d\n", cipher->min_keysize);
  219.             fprintf(stdout, "max_keysize: %d\n", cipher->max_keysize);
  220.             break;
  221.         case CRYPTOCFGA_REPORT_LARVAL:
  222.         case CRYPTOCFGA_REPORT_COMPRESS:
  223.         default:
  224.             break;
  225.     }
  226. }
  227.  
  228. static int cb_func(struct nl_msg *msg, void *arg)
  229. {
  230.     struct rtattr *attrs[CRYPTOCFGA_MAX + 1], *rta;
  231.     int len, *count;
  232.     enum crypto_attr_type_t t;
  233.     struct crypto_user_alg *ualg;
  234.     struct nlmsghdr *n = nlmsg_hdr(msg);
  235.     count = (unsigned int *)arg;
  236.  
  237.     if (CRYPTO_MSG_GETALG != n->nlmsg_type)
  238.     {
  239.         /* no, thanks */
  240.         return NL_SKIP;
  241.     }
  242.  
  243.     ualg = NLMSG_DATA(n);
  244.     len = n->nlmsg_len - NLMSG_SPACE(sizeof(*ualg));
  245.     rta = CR_RTA(ualg);
  246.  
  247.     memset(&attrs, 0, sizeof(attrs));
  248.     while (RTA_OK(rta, len))
  249.     {
  250.         if (CRYPTO_MSG_GETALG >= rta->rta_type && NULL == attrs[rta->rta_type])
  251.         {
  252.             attrs[rta->rta_type] = rta;
  253.         }
  254.         rta = RTA_NEXT(rta, len);
  255.     }
  256.  
  257.     for (t = CRYPTOCFGA_REPORT_LARVAL; __CRYPTOCFGA_MAX > t; ++t)
  258.     {
  259.         if (attrs[t])
  260.         {
  261.             ++(*count);
  262.             log_algo(ualg, t, RTA_DATA(attrs[t]), *count);
  263.             break;
  264.         }
  265.     }
  266.  
  267.     return NL_OK;
  268. }
  269.  
  270. int main(int argc, char *argv[])
  271. {
  272.     int err;
  273.     unsigned int count = 0;
  274.     struct nl_sock *sk;
  275.     struct rtgenmsg rtg = {
  276.         .rtgen_family = AF_UNSPEC,
  277.     };
  278.  
  279.     sk = nl_socket_alloc();
  280.     err = nl_connect(sk, NETLINK_CRYPTO);
  281.     if (0 > err)
  282.     {
  283.         nl_socket_free(sk);
  284.         fprintf(stderr, "%s:%u error connect: %s\n", __func__, __LINE__,
  285.                 nl_geterror(err));
  286.         return err;
  287.     }
  288.  
  289.     err = nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, cb_func, &count);
  290.     if (0 > err)
  291.     {
  292.         fprintf(stderr, "%s:%u netlink callback registation failed: %s",
  293.                 __func__, __LINE__, nl_geterror(err));
  294.         return err;
  295.     }
  296.  
  297.     if (1 < argc && 0 == strcmp(argv[1], "-p"))
  298.     {
  299.         nl_socket_enable_msg_peek(sk);
  300.     }
  301.     err = nl_send_simple(sk, CRYPTO_MSG_GETALG, NLM_F_DUMP | NLM_F_REQUEST,
  302.             &rtg, sizeof(rtg));
  303.  
  304.     err = nl_recvmsgs_default(sk);
  305.     if (0 > err)
  306.     {
  307.         fprintf(stderr, "%s:%u error reading response from netlink: %s",
  308.                 __func__, __LINE__, nl_geterror(err));
  309.         return err;
  310.     }
  311.     nl_socket_free(sk);
  312.  
  313.     return err;
  314. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement