1  /* Test the functions defined in byteorder.h.
       2   *
       3   * Written by Zack Weinberg <zackw at panix.com> in 2017.
       4   *
       5   * No copyright is claimed, and the software is hereby placed in the public
       6   * domain.  In case this attempt to disclaim copyright and place the software
       7   * in the public domain is deemed null and void, then the software is
       8   * Copyright (c) 2017 Zack Weinberg and it is hereby released to the
       9   * general public under the following terms:
      10   *
      11   * Redistribution and use in source and binary forms, with or without
      12   * modification, are permitted.
      13   *
      14   * There's ABSOLUTELY NO WARRANTY, express or implied.
      15   */
      16  
      17  #include "crypt-port.h"
      18  #include "byteorder.h"
      19  
      20  #include <inttypes.h>
      21  #include <stdio.h>
      22  
      23  struct test_32
      24  {
      25    uint32_t val;
      26    unsigned char bytes[4];
      27  };
      28  
      29  struct test_64
      30  {
      31    uint64_t val;
      32    unsigned char bytes[8];
      33  };
      34  
      35  #define Z(x) ((unsigned int)(unsigned char)(x)) /* zero extend char */
      36  
      37  static int
      38  test_le32 (void)
      39  {
      40    static const struct test_32 cases[] =
      41    {
      42      { 0x00000000, "\x00\x00\x00\x00" },
      43      { 0xFF000000, "\x00\x00\x00\xFF" },
      44      { 0x00FF0000, "\x00\x00\xFF\x00" },
      45      { 0x0000FF00, "\x00\xFF\x00\x00" },
      46      { 0x000000FF, "\xFF\x00\x00\x00" },
      47      { 0x01234567, "\x67\x45\x23\x01" },
      48    };
      49    size_t n_cases = ARRAY_SIZE (cases);
      50    size_t i;
      51    uint32_t v;
      52    unsigned char x[4];
      53    int status = 0;
      54  
      55    for (i = 0; i < n_cases; i++)
      56      {
      57        v = le32_to_cpu (cases[i].bytes);
      58        if (v != cases[i].val)
      59          {
      60            printf ("FAIL: le32_to_cpu: %02x %02x %02x %02x -> "
      61                    "%08"PRIx32" != %08"PRIx32"\n",
      62                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
      63                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]),
      64                    v, cases[i].val);
      65            status = 1;
      66          }
      67  
      68        cpu_to_le32 (x, cases[i].val);
      69        if (memcmp (x, cases[i].bytes, 4))
      70          {
      71            printf ("FAIL: cpu_to_le32: %08"PRIx32" -> "
      72                    "%02x %02x %02x %02x != %02x %02x %02x %02x\n",
      73                    cases[i].val,
      74                    Z(x[0]), Z(x[1]), Z(x[2]), Z(x[3]),
      75                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
      76                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]));
      77            status = 1;
      78          }
      79      }
      80  
      81    return status;
      82  }
      83  
      84  static int
      85  test_be32 (void)
      86  {
      87    static const struct test_32 cases[] =
      88    {
      89      { 0x00000000, "\x00\x00\x00\x00" },
      90      { 0xFF000000, "\xFF\x00\x00\x00" },
      91      { 0x00FF0000, "\x00\xFF\x00\x00" },
      92      { 0x0000FF00, "\x00\x00\xFF\x00" },
      93      { 0x000000FF, "\x00\x00\x00\xFF" },
      94      { 0x01234567, "\x01\x23\x45\x67" },
      95    };
      96    size_t n_cases = ARRAY_SIZE (cases);
      97    size_t i;
      98    uint32_t v;
      99    unsigned char x[4];
     100    int status = 0;
     101  
     102    for (i = 0; i < n_cases; i++)
     103      {
     104        v = be32_to_cpu (cases[i].bytes);
     105        if (v != cases[i].val)
     106          {
     107            printf ("FAIL: be32_to_cpu: %02x %02x %02x %02x -> "
     108                    "%08"PRIx32" != %08"PRIx32"\n",
     109                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
     110                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]),
     111                    v, cases[i].val);
     112            status = 1;
     113          }
     114  
     115        cpu_to_be32 (x, cases[i].val);
     116        if (memcmp (x, cases[i].bytes, 4))
     117          {
     118            printf ("FAIL: cpu_to_be32: %08"PRIx32" -> "
     119                    "%02x %02x %02x %02x != %02x %02x %02x %02x\n",
     120                    cases[i].val,
     121                    Z(x[0]), Z(x[1]), Z(x[2]), Z(x[3]),
     122                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
     123                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]));
     124            status = 1;
     125          }
     126      }
     127  
     128    return status;
     129  }
     130  
     131  static int
     132  test_le64 (void)
     133  {
     134    static const struct test_64 cases[] =
     135    {
     136      { 0x0000000000000000ull, "\x00\x00\x00\x00\x00\x00\x00\x00" },
     137      { 0x00000000000000FFull, "\xFF\x00\x00\x00\x00\x00\x00\x00" },
     138      { 0x000000000000FF00ull, "\x00\xFF\x00\x00\x00\x00\x00\x00" },
     139      { 0x0000000000FF0000ull, "\x00\x00\xFF\x00\x00\x00\x00\x00" },
     140      { 0x00000000FF000000ull, "\x00\x00\x00\xFF\x00\x00\x00\x00" },
     141      { 0x000000FF00000000ull, "\x00\x00\x00\x00\xFF\x00\x00\x00" },
     142      { 0x0000FF0000000000ull, "\x00\x00\x00\x00\x00\xFF\x00\x00" },
     143      { 0x00FF000000000000ull, "\x00\x00\x00\x00\x00\x00\xFF\x00" },
     144      { 0xFF00000000000000ull, "\x00\x00\x00\x00\x00\x00\x00\xFF" },
     145      { 0x0123456789ABCDEFull, "\xEF\xCD\xAB\x89\x67\x45\x23\x01" },
     146    };
     147    size_t n_cases = ARRAY_SIZE (cases);
     148    size_t i;
     149    uint64_t v;
     150    unsigned char x[8];
     151    int status = 0;
     152  
     153    for (i = 0; i < n_cases; i++)
     154      {
     155        v = le64_to_cpu (cases[i].bytes);
     156        if (v != cases[i].val)
     157          {
     158            printf ("FAIL: le64_to_cpu: %02x%02x %02x%02x %02x%02x %02x%02x "
     159                    "-> %016"PRIx64" != %016"PRIx64"\n",
     160                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
     161                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]),
     162                    Z(cases[i].bytes[4]), Z(cases[i].bytes[5]),
     163                    Z(cases[i].bytes[6]), Z(cases[i].bytes[7]),
     164                    v, cases[i].val);
     165            status = 1;
     166          }
     167  
     168        cpu_to_le64 (x, cases[i].val);
     169        if (memcmp (x, cases[i].bytes, 8))
     170          {
     171            printf ("FAIL: cpu_to_le64: %016"PRIx64" -> "
     172                    "%02x%02x %02x%02x %02x%02x %02x%02x != "
     173                    "%02x%02x %02x%02x %02x%02x %02x%02x\n",
     174                    cases[i].val,
     175                    Z(x[0]), Z(x[1]), Z(x[2]), Z(x[3]),
     176                    Z(x[4]), Z(x[5]), Z(x[6]), Z(x[7]),
     177                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
     178                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]),
     179                    Z(cases[i].bytes[4]), Z(cases[i].bytes[5]),
     180                    Z(cases[i].bytes[6]), Z(cases[i].bytes[7]));
     181            status = 1;
     182          }
     183      }
     184  
     185    return status;
     186  }
     187  
     188  static int
     189  test_be64 (void)
     190  {
     191    static const struct test_64 cases[] =
     192    {
     193      { 0x0000000000000000ull, "\x00\x00\x00\x00\x00\x00\x00\x00" },
     194      { 0x00000000000000FFull, "\x00\x00\x00\x00\x00\x00\x00\xFF" },
     195      { 0x000000000000FF00ull, "\x00\x00\x00\x00\x00\x00\xFF\x00" },
     196      { 0x0000000000FF0000ull, "\x00\x00\x00\x00\x00\xFF\x00\x00" },
     197      { 0x00000000FF000000ull, "\x00\x00\x00\x00\xFF\x00\x00\x00" },
     198      { 0x000000FF00000000ull, "\x00\x00\x00\xFF\x00\x00\x00\x00" },
     199      { 0x0000FF0000000000ull, "\x00\x00\xFF\x00\x00\x00\x00\x00" },
     200      { 0x00FF000000000000ull, "\x00\xFF\x00\x00\x00\x00\x00\x00" },
     201      { 0xFF00000000000000ull, "\xFF\x00\x00\x00\x00\x00\x00\x00" },
     202      { 0x0123456789ABCDEFull, "\x01\x23\x45\x67\x89\xAB\xCD\xEF" },
     203    };
     204    size_t n_cases = ARRAY_SIZE (cases);
     205    size_t i;
     206    uint64_t v;
     207    unsigned char x[8];
     208    int status = 0;
     209  
     210    for (i = 0; i < n_cases; i++)
     211      {
     212        v = be64_to_cpu (cases[i].bytes);
     213        if (v != cases[i].val)
     214          {
     215            printf ("FAIL: be64_to_cpu: %02x%02x %02x%02x %02x%02x %02x%02x "
     216                    "-> %016"PRIx64" != %016"PRIx64"\n",
     217                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
     218                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]),
     219                    Z(cases[i].bytes[4]), Z(cases[i].bytes[5]),
     220                    Z(cases[i].bytes[6]), Z(cases[i].bytes[7]),
     221                    v, cases[i].val);
     222            status = 1;
     223          }
     224  
     225        cpu_to_be64 (x, cases[i].val);
     226        if (memcmp (x, cases[i].bytes, 8))
     227          {
     228            printf ("FAIL: cpu_to_be64: %016"PRIx64" -> "
     229                    "%02x%02x %02x%02x %02x%02x %02x%02x != "
     230                    "%02x%02x %02x%02x %02x%02x %02x%02x\n",
     231                    cases[i].val,
     232                    Z(x[0]), Z(x[1]), Z(x[2]), Z(x[3]),
     233                    Z(x[4]), Z(x[5]), Z(x[6]), Z(x[7]),
     234                    Z(cases[i].bytes[0]), Z(cases[i].bytes[1]),
     235                    Z(cases[i].bytes[2]), Z(cases[i].bytes[3]),
     236                    Z(cases[i].bytes[4]), Z(cases[i].bytes[5]),
     237                    Z(cases[i].bytes[6]), Z(cases[i].bytes[7]));
     238            status = 1;
     239          }
     240      }
     241  
     242    return status;
     243  }
     244  
     245  int
     246  main (void)
     247  {
     248    int status = 0;
     249    status |= test_le32 ();
     250    status |= test_be32 ();
     251    status |= test_le64 ();
     252    status |= test_be64 ();
     253    return status;
     254  }