SHARE
TWEET

spintop.c

a guest Nov 2nd, 2012 43 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * spintop.c
  3.  *
  4.  *
  5.  * Copyright (c) 2012 Gonzalo J. Carracedo
  6.  * < BatchDrake (at) gmail (dot) com >
  7.  *
  8.  * SpinTop: implements bsign-style signature self-verification at runtime, thus
  9.  * preventing infected / modified binaries to run.
  10.  *
  11.  * SpinTop is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * SpinTop is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *  
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with Slabot; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  24.  *
  25.  * Note: SHA1 implementation comes directly from bsign's code.
  26.  */
  27.  
  28. #define _FILE_OFFSET_BITS 64
  29.  
  30. #include <stdlib.h>
  31. #include <elf.h>
  32. #include <stdarg.h>
  33. #include <fcntl.h>
  34. #include <unistd.h>
  35. #include <syscall.h>
  36. #include <sys/types.h>
  37. #include <sys/mman.h>
  38. #include <stdint.h>
  39. #include <gpgme.h>
  40. #include <stdint.h>
  41.  
  42. #include "standard.h"
  43. #include "sha1.h"
  44.  
  45. #ifndef SPINTOP_TRUSTABLE_FINGERPRINT
  46.   #error SPINTOP_TRUSTABLE_FINGERPRINT is not defined, please provide a valid signature fingerprint at compile time.
  47. #endif
  48.  
  49. #if UINTPTR_MAX == 0xffffffff
  50.   #define Elf_Ehdr Elf32_Ehdr
  51.   #define Elf_Shdr Elf32_Shdr
  52. #elif UINTPTR_MAX == 0xffffffffffffffff
  53.   #define Elf_Ehdr Elf64_Ehdr
  54.   #define Elf_Shdr Elf64_Shdr
  55. #else
  56.   #error Unsupported machine
  57. #endif
  58.  
  59. #define warning(fmt, arg...) st_printf ("spintop warning: " fmt, ##arg)
  60. #define error(fmt, arg...) st_printf ("\033[1;31mspintop error: " fmt "\033[0m", ##arg)
  61.  
  62.  
  63. typedef int8_t byte;
  64. typedef int8_t int8;
  65. typedef uint8_t unsigned8;
  66. typedef int16_t int16;
  67. typedef uint16_t unsigned16;
  68.  
  69. typedef int32_t int32;
  70. typedef uint32_t unsigned32;
  71.  
  72. typedef int64_t int64;
  73. typedef uint64_t unsigned64;
  74.  
  75.  
  76. /* SHA1 functions */
  77. const char *
  78. sha1_get_info( int algo, size_t *contextsize,
  79.                byte **r_asnoid, int *r_asn_len, int *r_mdlen,
  80.                void (**r_init)( void *c ),
  81.                void (**r_write)( void *c, byte *buf, size_t nbytes ),
  82.                void (**r_final)( void *c ),
  83.                byte *(**r_read)( void *c )
  84.              );
  85.  
  86. /* System calls */
  87. static inline int     st_open (const char *, int);
  88. static inline int     st_close (int);        
  89. static inline int     st_write (int, const void *, int);
  90. static inline int     st_read (int, void *, int);
  91. static inline int     st_lseek (int, int, int);
  92. static inline pid_t   st_getpid (void);
  93. static inline int     st_exit (int code);
  94. void *                st_mmap (void *, size_t, int, int, int, off_t) __attribute__ ((visibility ("hidden")));
  95. int                   st_munmap (void *, size_t) __attribute__ ((visibility ("hidden")));
  96.  
  97.  
  98. /* Library functions */
  99. static size_t         st_vsnprintf (char *, size_t, const char *, va_list);
  100. static void           st_printf (const char *, ...);
  101. static void           st_snprintf (char *, size_t, const char *, ...);
  102. static inline size_t  st_strlen (const char *);
  103. static inline int     st_memset (void *, int, size_t);
  104. static inline int     st_strcmp (const char *, const char *);
  105. static inline void *  st_memcpy (void *, const void *, size_t);
  106.  
  107. /*
  108.  Definitions end here
  109.  -----8<-----------------------------------------------------------------------
  110.  Spintop code starts here
  111. */
  112.  
  113. /* Just a function to return a hash of the binary */
  114. char *
  115. sha1_hash_binary (void *elfbase, size_t elflength)
  116. {
  117.   size_t ctx_size;
  118.   void (*pfn_init) (void*);
  119.   void (*pfn_write) (void*, byte*, size_t);
  120.   void (*pfn_final) (void*);
  121.   byte* (*pfn_read) (void*);
  122.   byte* r_asnoid;
  123.   int r_asnlen;
  124.   int r_mdlen;
  125.   void *ctx;
  126.  
  127.   static char result[20];
  128.  
  129.   sha1_get_info (2, &ctx_size, &r_asnoid, &r_asnlen, &r_mdlen,
  130.     &pfn_init, &pfn_write, &pfn_final, &pfn_read);
  131.    
  132.   if ((ctx = malloc (ctx_size)) == NULL)
  133.   {
  134.     warning ("cannot allocate %d bytes, exiting\n", ctx_size);
  135.     st_exit (127);
  136.   }
  137.  
  138.   (*pfn_init) (ctx);
  139.   (*pfn_write) (ctx, elfbase, elflength);
  140.   (*pfn_final) (ctx);
  141.  
  142.   st_memcpy (result, (*pfn_read) (ctx), 20);
  143.  
  144.   free (ctx);
  145.  
  146.   return result;
  147. }
  148.  
  149. /* Verify whether GPG signature works */
  150. static int
  151. gpg_signature_verify (const void *signature_data, size_t signature_length, void *hash_data, size_t hash_len)
  152. {
  153.   gpgme_ctx_t ctx;
  154.   gpgme_error_t err;
  155.   gpgme_data_t sig_buf, hash_buf;
  156.   gpgme_verify_result_t result;
  157.   int errcode;
  158.  
  159.   /* It's REALLY IMPORTANT that the fingerprint is stored as a local variable
  160.      instead as a constant written somewhere in .rodata. Like this, the
  161.      fingerprint will be initialized with a series of mov's, splitting
  162.      it, making it more difficult to find from a virus perspective. */
  163.   char expected_fingerprint[] = SPINTOP_TRUSTABLE_FINGERPRINT;
  164.    
  165.   (void) gpgme_check_version (NULL);
  166.  
  167.   errcode = -1;
  168.  
  169.   if ((err = gpgme_new (&ctx)) != 0)
  170.   {
  171.     warning ("cannot create GPGME context, cannot continue.\n");
  172.    
  173.     return -1;
  174.   }
  175.  
  176.   if ((err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP)) != 0)
  177.   {
  178.     warning ("cannot select OpenPGP as protocol, cannot continue.\n");
  179.    
  180.     goto ctx_cleanup;
  181.   }
  182.  
  183.   /* Checking a valid message.  */
  184.   if ((err = gpgme_data_new_from_mem (&sig_buf, signature_data, signature_length, 0)) != 0)
  185.   {
  186.     warning ("cannot copy signature, cannot continue.\n");
  187.    
  188.     goto ctx_cleanup;
  189.   }
  190.  
  191.   if ((err = gpgme_data_new_from_mem (&hash_buf, hash_data, hash_len, 0)) != 0)
  192.   {
  193.     warning ("cannot copy hash, cannot continue.\n");
  194.    
  195.     goto sig_cleanup;
  196.   }
  197.  
  198.   if ((err = gpgme_op_verify (ctx, sig_buf, hash_buf, NULL)) != 0)
  199.   {
  200.     error ("verification error (%s), operation failed, cannot continue.\n", gpgme_strerror (err));
  201.     goto all_cleanup;
  202.   }
  203.  
  204.   result = gpgme_op_verify_result (ctx);
  205.  
  206.   if (gpg_err_code (result->signatures->status) != GPG_ERR_NO_ERROR)
  207.   {
  208.     error ("MODIFIED BINARY DETECTED (%s)\n", gpg_strerror (gpg_err_code (result->signatures->status)));
  209.     error ("SOMEBODY CALL DE COPS\n");
  210.     goto all_cleanup;
  211.   }
  212.  
  213.   if (result->signatures->wrong_key_usage)
  214.   {
  215.     warning ("wrong key usage!\n");
  216.    
  217.     goto all_cleanup;
  218.   }
  219.  
  220.   if (result->signatures->validity != GPGME_VALIDITY_FULL)
  221.   {
  222.     warning ("signature is not fully valid, cannot continue.\n");
  223.    
  224.     goto all_cleanup;
  225.   }
  226.  
  227.   if (gpg_err_code (result->signatures->validity_reason) != GPG_ERR_NO_ERROR)
  228.   {
  229.     warning ("validity encountered errors, cannot continue.");
  230.     goto all_cleanup;
  231.   }
  232.  
  233.   if (st_strcmp (result->signatures->fpr, expected_fingerprint) != 0)
  234.   {
  235.     error ("WARNING: UNEXPECTED FINGERPRINT \"%s\"\n", result->signatures->fpr);
  236.     error ("SOMEBODY TRIED TO FOOL US.\n");
  237.    
  238.     goto all_cleanup;
  239.   }
  240.  
  241.   errcode = 0;
  242.  
  243. all_cleanup:
  244.   gpgme_data_release (hash_buf);
  245.  
  246. sig_cleanup:
  247.   gpgme_data_release (sig_buf);
  248.  
  249. ctx_cleanup:
  250.   gpgme_release (ctx);
  251.  
  252.   return errcode;
  253. }
  254.  
  255. /* Find a section inside an ELF */
  256. static const Elf_Shdr *
  257. elf_section_lookup (const void *base, size_t length, const char *name)
  258. {
  259.   const Elf_Ehdr *header;
  260.   const Elf_Shdr *shdr;
  261.   const char *section_names;
  262.   unsigned long names_len;
  263.  
  264.   int i;
  265.  
  266.   header = (Elf_Ehdr *) base;
  267.  
  268.   if (header->e_shoff + header->e_shnum * header->e_shentsize > length)
  269.     return NULL;
  270.  
  271.   shdr = (Elf_Shdr *) (base +
  272.                        header->e_shoff +
  273.                        header->e_shstrndx * header->e_shentsize);
  274.  
  275.   if (shdr->sh_offset >= length)
  276.     return NULL;
  277.    
  278.   section_names = (const char *) (base + shdr->sh_offset);
  279.   names_len = shdr->sh_size;
  280.  
  281.   for (i = 0; i < header->e_shnum; ++i)
  282.   {
  283.     shdr = (Elf_Shdr *) (base + header->e_shoff + i * header->e_shentsize);
  284.  
  285.     if (shdr->sh_name > names_len)
  286.       continue;
  287.      
  288.     if (st_strcmp (name, shdr->sh_name + section_names) == 0)
  289.       return shdr;
  290.   }
  291.  
  292.   return NULL;
  293. }
  294.  
  295. /* Check if this ELF is ready to run */
  296. static int
  297. elf_selfcheck (void *base, size_t length)
  298. {
  299.   const Elf_Ehdr *header;
  300.   const Elf_Shdr *signshdr;
  301.   const void *sign_base;  
  302.   const char *str_sign_base;
  303.   char *new_hash;
  304.   size_t new_hash_len;
  305.  
  306.   char *signature_copy;
  307.   uint16_t sigsize;
  308.  
  309.   int i;
  310.  
  311.   header = (Elf_Ehdr *) base;
  312.  
  313.   if (header->e_ident[EI_MAG0] != ELFMAG0 ||
  314.       header->e_ident[EI_MAG1] != ELFMAG1 ||
  315.       header->e_ident[EI_MAG2] != ELFMAG2 ||
  316.       header->e_ident[EI_MAG3] != ELFMAG3)
  317.   {
  318.     warning ("not an ELF file!\n");
  319.     return -1;
  320.   }
  321.  
  322.   if ((signshdr = elf_section_lookup (base, length, "signature")) == NULL)
  323.   {
  324.     warning ("binary is not signed (yet). Use bsign(1) to generate a signature before running it.\n");
  325.     return -1;
  326.   }
  327.  
  328.   if (signshdr->sh_offset + signshdr->sh_size > length)
  329.   {
  330.     warning ("signature bytes out of bounds!\n");
  331.     return -1;
  332.   }
  333.  
  334.   sign_base = base + signshdr->sh_offset;
  335.   str_sign_base = (const char *) sign_base;
  336.  
  337.   if (str_sign_base[0] != '#' ||
  338.       str_sign_base[1] != '1' ||
  339.       str_sign_base[2] != ';')
  340.   {
  341.     warning ("unrecognized signature format!\n");
  342.     return -1;
  343.   }
  344.  
  345.  
  346.   for (i = 3; i < signshdr->sh_size; ++i)
  347.     if (str_sign_base[i] == '\n')
  348.       break;
  349.  
  350.   if (str_sign_base[i++] != '\n')
  351.   {
  352.     warning ("cannot find signature start!\n");
  353.     return -1;
  354.   }
  355.  
  356.   i += 20;
  357.  
  358.   new_hash_len = i;
  359.  
  360.   if ((new_hash = malloc (new_hash_len)) == NULL)
  361.   {
  362.     warning ("malloc: cannot alloc %d bytes\n", i);
  363.     return -1;
  364.   }
  365.  
  366.   st_memcpy (new_hash, sign_base, new_hash_len);
  367.  
  368.   sigsize = 0;
  369.  
  370.   sigsize |= (unsigned) str_sign_base[i++] << 8;
  371.   sigsize |= (unsigned) str_sign_base[i++];
  372.  
  373.   if ((signature_copy = malloc (sigsize)) == NULL)
  374.   {
  375.     warning ("malloc: cannot alloc %d bytes\n", i);
  376.     return -1;
  377.   }
  378.  
  379.   st_memcpy (signature_copy, str_sign_base + i, sigsize);
  380.  
  381.   st_memset (base + signshdr->sh_offset, 0, signshdr->sh_size);
  382.  
  383.   st_memcpy (new_hash + new_hash_len - 20, sha1_hash_binary (base, length), 20);
  384.  
  385.   if (gpg_signature_verify (signature_copy, sigsize, new_hash, new_hash_len) == -1)
  386.   {
  387.     free (new_hash);
  388.     free (signature_copy);
  389.     return -1;
  390.   }
  391.  
  392.   free (new_hash);
  393.   free (signature_copy);
  394.    
  395.   return 0;
  396. }
  397.  
  398. /* Entry point */
  399. __attribute__ ((constructor)) static void
  400. spintop_entry (void)
  401. {
  402.   char procpath[100];
  403.   int fd, ret;
  404.   ssize_t bin_length;
  405.   void *base;
  406.  
  407.   st_snprintf (procpath, sizeof (procpath), "/proc/%d/exe", st_getpid ());
  408.  
  409.   if ((fd = st_open (procpath, O_RDONLY)) < 0)
  410.   {
  411.     warning ("cannot open %s for reading: errno %d\n", procpath, -fd);
  412.     st_exit (127);
  413.   }
  414.  
  415.   if ((bin_length = st_lseek (fd, 0, SEEK_END)) < 0)
  416.   {
  417.     warning ("cannot self-measure executable size: errno %d\n", -bin_length);
  418.     st_exit (127);
  419.   }
  420.  
  421.   if ((unsigned) (base = st_mmap (NULL, bin_length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) & 0xfff)
  422.   {
  423.     warning ("mmap failed\n");
  424.     st_exit (127);
  425.   }
  426.  
  427.   if (elf_selfcheck (base, bin_length) == -1)
  428.     st_exit (127);
  429.  
  430.   st_close (fd);
  431.  
  432.   if ((ret = st_munmap (base, bin_length)) < 0)
  433.   {
  434.     warning ("cannot munmap!\n");
  435.     st_exit (127);
  436.   }
  437. }
  438.  
  439.  
  440.  
  441. /*
  442.  Spintop code ends here
  443.  -----8<-----------------------------------------------------------------------
  444.  Library functions start here
  445. */
  446.  
  447. #define ST_PRINTF_BUFSIZE 256
  448.  
  449. /* Directly copied from Wikipedia. Yes, so what? I don't need a super-efficient
  450.    implementation of this */
  451. static inline int
  452. st_strcmp (const char *s1, const char *s2)
  453. {
  454.    unsigned char uc1, uc2;
  455.    /* Move s1 and s2 to the first differing characters
  456.       in each string, or the ends of the strings if they
  457.       are identical.  */
  458.    while (*s1 != '\0' && *s1 == *s2) {
  459.        s1++;
  460.        s2++;
  461.    }
  462.    /* Compare the characters as unsigned char and
  463.       return the difference.  */
  464.    uc1 = (*(unsigned char *) s1);
  465.    uc2 = (*(unsigned char *) s2);
  466.    return ((uc1 < uc2) ? -1 : (uc1 > uc2));
  467. }
  468.  
  469. static inline int
  470. st_memset (void *dest, int code, size_t len)
  471. {
  472.   int olen = len;
  473.   while (len--)
  474.     *((char *) dest++) = code;
  475.  
  476.   return olen;
  477. }
  478.  
  479. static inline void *
  480. st_memcpy (void *dest, const void *orig, size_t len)
  481. {
  482.   while (len--)
  483.     *((char *) dest++) = *((char *) orig++);
  484.  
  485.   return dest;
  486. }
  487.  
  488. static void
  489. st_printf (const char *fmt, ...)
  490. {
  491.   va_list ap;
  492.   char buffer[ST_PRINTF_BUFSIZE];
  493.   size_t len;
  494.  
  495.   va_start (ap, fmt);
  496.  
  497.   len = st_vsnprintf (buffer, ST_PRINTF_BUFSIZE, fmt, ap);
  498.  
  499.   st_write (2, buffer, len);
  500.  
  501.   va_end (ap);
  502. }
  503.  
  504. static void
  505. st_snprintf (char *buffer, size_t len, const char *fmt, ...)
  506. {
  507.   va_list ap;
  508.   va_start (ap, fmt);
  509.  
  510.   len = st_vsnprintf (buffer, ST_PRINTF_BUFSIZE, fmt, ap);
  511.  
  512.   va_end (ap);
  513. }
  514.  
  515. #define APPEND_CHAR(output, size, c) \
  516.   do                                 \
  517.   {                                  \
  518.     if (*size)                       \
  519.     {                                \
  520.       *output++ = c;                 \
  521.       --(*size);                     \
  522.     }                                \
  523.     else                             \
  524.       return output;                 \
  525.   }                                  \
  526.   while (0)
  527.  
  528. static char *
  529. convert_decimal (char *output, size_t *size, int n)
  530. {
  531.   int copy;
  532.   int i;
  533.   char nbuf[30];
  534.  
  535.   copy = n;
  536.   if (copy < 0)
  537.     copy = -copy;
  538.  
  539.   for (i = 0; copy; ++i)
  540.   {
  541.     nbuf[i] = '0' + copy % 10;
  542.     copy /= 10;
  543.   }
  544.  
  545.   if (n < 0)
  546.     APPEND_CHAR (output, size, '-');
  547.  
  548.   if (!i)
  549.     APPEND_CHAR (output, size, '0');
  550.   else
  551.     for (--i; i >= 0; --i)
  552.       APPEND_CHAR (output, size, nbuf[i]);
  553.      
  554.   return output;
  555. }
  556.      
  557.    
  558. static char *
  559. convert_octal (char *output, size_t *size, unsigned int n)
  560. {
  561.   int copy;
  562.   int i;
  563.   char nbuf[30];
  564.  
  565.   copy = n;
  566.   if (copy < 0)
  567.     copy = -copy;
  568.  
  569.   for (i = 0; copy; ++i)
  570.   {
  571.     nbuf[i] = '0' + copy % 8;
  572.     copy /= 8;
  573.   }
  574.  
  575.   if (!i)
  576.     APPEND_CHAR (output, size, '0');
  577.   else
  578.     for (--i; i >= 0; --i)
  579.       APPEND_CHAR (output, size, nbuf[i]);
  580.      
  581.   return output;
  582. }
  583.  
  584. static char *
  585. convert_hex64 (char *output, size_t *size, uint64_t n, int upper)
  586. {
  587.   int copy;
  588.   int i;
  589.   char nbuf[30];
  590.   char hexachars_upper[] = "0123456789ABCDEF";
  591.   char hexachars_lower[] = "0123456789abcdef";
  592.  
  593.   for (i = 0; n; ++i)
  594.   {
  595.     nbuf[i] = upper ? hexachars_upper [n % 16] : hexachars_lower [n % 16];
  596.     n /= 16;
  597.   }
  598.  
  599.   if (!i)
  600.     APPEND_CHAR (output, size, '0');
  601.   else
  602.     for (--i; i >= 0; --i)
  603.       APPEND_CHAR (output, size, nbuf[i]);
  604.      
  605.   return output;
  606. }
  607.  
  608. static char *
  609. convert_DWORD (char *output, size_t *size, uint32_t num, int upper, int sep)
  610. {
  611.   char hexachars_upper[] = "0123456789ABCDEF";
  612.   char hexachars_lower[] = "0123456789abcdef";
  613.  
  614.   int i;
  615.  
  616.   for (i = 7; i >= 0; --i)
  617.   {
  618.     if (i == 3 && sep)
  619.       APPEND_CHAR (output, size, ':');
  620.    
  621.     APPEND_CHAR (output, size, upper ? hexachars_upper[(num & 0xf << i * 4) >> i * 4] :
  622.               hexachars_lower[(num & 0xf << i * 4) >> i * 4]);
  623.   }
  624.  
  625.   return output;
  626. }
  627.  
  628. static char *
  629. convert_QWORD (char *output, size_t *size, uint64_t num, int upper, int sep)
  630. {
  631.   char hexachars_upper[] = "0123456789ABCDEF";
  632.   char hexachars_lower[] = "0123456789abcdef";
  633.  
  634.   int i;
  635.  
  636.   for (i = 15; i >= 0; --i)
  637.   {
  638.     if (i == 7 && sep)
  639.       APPEND_CHAR (output, size, ':');
  640.      
  641.     APPEND_CHAR (output, size, upper ? hexachars_upper[(num & 0xf << i * 4) >> i * 4] :
  642.               hexachars_lower[(num & 0xf << i * 4) >> i * 4]);
  643.   }
  644.  
  645.   return output;
  646. }
  647.  
  648. static char *
  649. convert_byte (char *output, size_t *size, uint32_t num, int upper)
  650. {
  651.   char hexachars_upper[] = "0123456789ABCDEF";
  652.   char hexachars_lower[] = "0123456789abcdef";
  653.  
  654.   APPEND_CHAR (output, size, upper ? hexachars_upper[(num & 0xf << 4) >> 4] :
  655.               hexachars_lower[(num & 0xf << 4) >> 4]);
  656.              
  657.   APPEND_CHAR (output, size, upper ? hexachars_upper[(num & 0xf)] :
  658.               hexachars_lower[(num & 0xf)]);
  659.              
  660.   return output;
  661. }
  662.  
  663. static char *
  664. st_vsnprintf_append_char (char *output, size_t *size, char c)
  665. {
  666.   APPEND_CHAR (output, size, c);
  667.  
  668.   return output;
  669. }
  670.  
  671. static char *
  672. st_vsnprintf_append_string (char *output, size_t *size, const char *s)
  673. {
  674.   while (*s)
  675.     APPEND_CHAR (output, size, *s++);
  676.  
  677.   return output;
  678. }
  679.  
  680. static size_t
  681. st_vsnprintf (char *output, size_t size, const char *fmt, va_list ap)
  682. {
  683.  
  684.   int len;
  685.   int i;
  686.   void *ptr;
  687.   size_t old;
  688.  
  689.   len = st_strlen (fmt);
  690.  
  691.   i = 0;
  692.  
  693.   old = size;
  694.  
  695.   --size;
  696.  
  697.   for (i = 0; i < len; ++i)
  698.   {
  699.     if (size <= 0)
  700.       break;
  701.      
  702.     if (fmt[i] == '%')
  703.     {
  704.       ++i;
  705.      
  706.       switch (fmt[i])
  707.       {
  708.         case 'd':
  709.           output = convert_decimal (output, &size, va_arg (ap, int));
  710.           break;
  711.          
  712.         case 'b':
  713.           output = convert_byte (output, &size, va_arg (ap, unsigned int), 0);
  714.           break;
  715.          
  716.         case 'B':
  717.           output = convert_byte (output, &size, va_arg (ap, unsigned int), 1);
  718.           break;
  719.          
  720.         case 'x':
  721.           output = convert_hex64 (output, &size, va_arg (ap, unsigned int), 0);
  722.           break;
  723.  
  724.         case 'o':
  725.           output = convert_octal (output, &size, va_arg (ap, unsigned int));
  726.           break;
  727.        
  728.         case 'X':
  729.           output = convert_hex64 (output, &size, va_arg (ap, unsigned int), 1);
  730.           break;
  731.        
  732.         case 'w':
  733.           output = convert_DWORD (output, &size, va_arg (ap, uint32_t), 0, 1);
  734.           break;
  735.        
  736.         case 'W':
  737.           output = convert_DWORD (output, &size, va_arg (ap, uint32_t), 1, 1);
  738.           break;
  739.        
  740.         case 'q':
  741.           output = convert_QWORD (output, &size, va_arg (ap, uint32_t), 0, 1);
  742.           break;
  743.        
  744.         case 'Q':
  745.           output = convert_QWORD (output, &size, va_arg (ap, uint32_t), 1, 1);
  746.           break;
  747.        
  748.         case 'y':
  749.           output = convert_DWORD (output, &size, va_arg (ap, uint32_t), 0, 0);
  750.           break;
  751.        
  752.         case 'Y':
  753.           output = convert_DWORD (output, &size, va_arg (ap, uint32_t), 1, 0);
  754.           break;
  755.          
  756.         case 'z':
  757.           output = convert_DWORD (output, &size, va_arg (ap, uint32_t), 0, 0);
  758.           break;
  759.        
  760.         case 'Z':
  761.           output = convert_DWORD (output, &size, va_arg (ap, uint32_t), 1, 0);
  762.           break;
  763.          
  764.         case 'c':
  765.           output = st_vsnprintf_append_char (output, &size, va_arg (ap, unsigned int));
  766.           break;
  767.          
  768.         case 'p':
  769.           ptr = va_arg (ap, void *);
  770.          
  771.           if (ptr == NULL)
  772.             output = st_vsnprintf_append_string (output, &size, "(null)");
  773.           else
  774.           {
  775.             output = st_vsnprintf_append_string (output, &size, "0x");
  776.             output = convert_hex64 (output, &size, (unsigned long) ptr, 0);
  777.           }
  778.          
  779.           break;
  780.          
  781.         case 's':
  782.           output = st_vsnprintf_append_string (output, &size, va_arg (ap, char *));
  783.           break;
  784.        
  785.         case '%':
  786.           output = st_vsnprintf_append_char (output, &size, '%');
  787.           break;
  788.          
  789.         case '\0':
  790.           return;
  791.       }
  792.     }
  793.     else
  794.       output = st_vsnprintf_append_char (output, &size, fmt[i]);
  795.   }
  796.  
  797.   *output = 0;
  798.  
  799.   return old - size - 1;
  800. }
  801.  
  802.  
  803. static inline size_t
  804. st_strlen (const char *string)
  805. {
  806.   size_t size = 0;
  807.   /* We aren't GNU hackers, the classical way works */
  808.  
  809.   while (*string++)
  810.     ++size;
  811.    
  812.   return size;
  813. }
  814.  
  815. /*
  816.  Library functions end here
  817.  -----8<-----------------------------------------------------------------------
  818.  System calls start here
  819. */
  820.  
  821.  
  822. static inline pid_t
  823. st_getpid (void)
  824. {
  825.   pid_t result;
  826.  
  827.   asm volatile ("int $0x80" : "=a" (result) : "a" (__NR_getpid));
  828.  
  829.   return result;
  830. }
  831.  
  832. static inline int
  833. st_write (int fd, const void *buf, int size)
  834. {
  835.   int ret;
  836.  
  837.   asm volatile ("xchg %%ebx, %%esi\n"
  838.                  "int $0x80\n"
  839.                  "xchg %%ebx, %%esi\n" : "=a" (ret) :
  840.                  "a" (__NR_write), "S" (fd), "c" (buf), "d" (size));
  841.    
  842.   return ret;
  843. }
  844.  
  845. static inline int
  846. st_read (int fd, void *buf, int size)
  847. {
  848.   int ret;
  849.  
  850.   asm volatile ("xchg %%ebx, %%esi\n"
  851.                  "int $0x80\n"
  852.                  "xchg %%ebx, %%esi\n" : "=a" (ret) :
  853.                  "a" (__NR_read), "S" (fd), "c" (buf), "d" (size)  :
  854.                  "memory"); /* read modifica la memoria */
  855.    
  856.   return ret;
  857. }
  858.  
  859. static inline int
  860. st_lseek (int fd, int offset, int whence)
  861. {
  862.   int ret;
  863.  
  864.   asm volatile ("xchg %%ebx, %%esi\n"
  865.                  "int $0x80\n"
  866.                  "xchg %%ebx, %%esi\n" : "=a" (ret) :
  867.                  "a" (__NR_lseek), "S" (fd), "c" (offset), "d" (whence));
  868.    
  869.   return ret;
  870. }
  871.  
  872. static inline int
  873. st_open (const char *path, int mode)
  874. {
  875.   int ret;
  876.  
  877.   asm volatile ("xchg %%ebx, %%esi\n"
  878.                  "int $0x80\n"
  879.                  "xchg %%ebx, %%esi\n" : "=a" (ret) :
  880.                  "a" (__NR_open), "S" (path), "c" (mode));
  881.    
  882.   return ret;
  883. }
  884.  
  885. static inline int
  886. st_close (int fd)
  887. {
  888.   int ret;
  889.  
  890.   asm volatile ("xchg %%ebx, %%esi\n"
  891.                  "int $0x80\n"
  892.                  "xchg %%ebx, %%esi\n" : "=a" (ret) :
  893.                  "a" (__NR_close), "S" (fd));
  894.    
  895.   return ret;
  896. }
  897.  
  898. static inline int
  899. st_exit (int code)
  900. {
  901.   asm volatile ("xchg %%ebx, %%esi\n"
  902.                  "int $0x80\n"
  903.                  "xchg %%ebx, %%esi\n" : :
  904.                  "a" (__NR_exit), "S" (code));
  905. }
  906.  
  907. asm (".section .text");
  908. asm ("st_munmap:");
  909. asm ("  mov    %ebx,%edx");
  910. asm ("  mov    0x8(%esp),%ecx");
  911. asm ("  mov    0x4(%esp),%ebx");
  912. asm ("  mov    $0x5b,%eax");
  913. asm ("  int    $0x80");
  914. asm ("  mov    %edx,%ebx");
  915. asm ("  ret");
  916.  
  917. asm ("st_mmap:");
  918. asm ("  push %eax");
  919. asm ("  pusha");
  920. asm ("  mov    0x28(%esp), %ebx"); /* Primer argumento */
  921. asm ("  mov    0x2c(%esp), %ecx"); /* Segundo argumento */
  922. asm ("  mov    0x30(%esp), %edx"); /* Tercer argumento */
  923. asm ("  mov    0x34(%esp), %esi"); /* Cuargo argumento */
  924. asm ("  mov    0x38(%esp), %edi"); /* Quinto argumnto */
  925. asm ("  mov    0x3c(%esp), %ebp"); /* Sexto argumento */
  926. asm ("  shr    $0xc, %ebp"); /* El kernel se espera directamente los 12 bits de página */
  927. asm ("  mov    $0xc0, %eax");
  928. asm ("  int    $0x80");
  929. asm ("  mov    %eax, 0x20(%esp)");
  930. asm ("  popa");
  931. asm ("  pop %eax");
  932. asm ("  ret");
  933.  
  934. /*
  935.  System calls end here
  936.  -----8<-----------------------------------------------------------------------
  937.  SHA1 implementation starts here
  938. */
  939.  
  940. #define u32 unsigned32
  941. #define DIM(v) (sizeof(v)/sizeof((v)[0]))
  942. #define DIMof(type,member)   DIM(((type *)0)->member)
  943.  
  944. typedef struct {
  945.     u32  h0,h1,h2,h3,h4;
  946.     u32  nblocks;
  947.     byte buf[64];
  948.     int  count;
  949. } SHA1_CONTEXT;
  950.  
  951.  
  952. #if defined(__GNUC__) && defined(__i386__)
  953. static inline u32
  954. rol(int n, u32 x)
  955. {
  956.         __asm__("roll %%cl,%0"
  957.                 :"=r" (x)
  958.                 :"0" (x),"c" (n));
  959.         return x;
  960. }
  961. #else
  962.   #define rol(n,x)  ( ((x) << (n)) | ((x) >> (32-(n))) )
  963. #endif
  964.  
  965.  
  966.  
  967.  
  968. void
  969. sha1_init( SHA1_CONTEXT *hd )
  970. {
  971.     hd->h0 = 0x67452301;
  972.     hd->h1 = 0xefcdab89;
  973.     hd->h2 = 0x98badcfe;
  974.     hd->h3 = 0x10325476;
  975.     hd->h4 = 0xc3d2e1f0;
  976.     hd->nblocks = 0;
  977.     hd->count = 0;
  978. }
  979.  
  980.  
  981. /****************
  982.  * Transform the message X which consists of 16 32-bit-words
  983.  */
  984. static void
  985. transform( SHA1_CONTEXT *hd, byte *data )
  986. {
  987.     u32 a,b,c,d,e,tm;
  988.     u32 x[16];
  989.  
  990.     /* get values from the chaining vars */
  991.     a = hd->h0;
  992.     b = hd->h1;
  993.     c = hd->h2;
  994.     d = hd->h3;
  995.     e = hd->h4;
  996.  
  997. #ifdef WORDS_BIGENDIAN
  998.     memcpy( x, data, 64 );
  999. #else
  1000.     { int i;
  1001.       byte *p2;
  1002.       for(i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
  1003.         p2[3] = *data++;
  1004.         p2[2] = *data++;
  1005.         p2[1] = *data++;
  1006.         p2[0] = *data++;
  1007.       }
  1008.     }
  1009. #endif
  1010.  
  1011.  
  1012. #define K1  0x5A827999L
  1013. #define K2  0x6ED9EBA1L
  1014. #define K3  0x8F1BBCDCL
  1015. #define K4  0xCA62C1D6L
  1016. #define F1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )
  1017. #define F2(x,y,z)   ( x ^ y ^ z )
  1018. #define F3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )
  1019. #define F4(x,y,z)   ( x ^ y ^ z )
  1020.  
  1021.  
  1022. #define M(i) ( tm =   x[i&0x0f] ^ x[(i-14)&0x0f] \
  1023.                     ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
  1024.                , (x[i&0x0f] = (tm << 1) | (tm >> 31)) )
  1025.  
  1026. #define R(a,b,c,d,e,f,k,m)  do { e += rol( 5, a )     \
  1027.                                       + f( b, c, d )  \
  1028.                                       + k             \
  1029.                                       + m;            \
  1030.                                  b = rol( 30, b );    \
  1031.                                } while(0)
  1032.     R( a, b, c, d, e, F1, K1, x[ 0] );
  1033.     R( e, a, b, c, d, F1, K1, x[ 1] );
  1034.     R( d, e, a, b, c, F1, K1, x[ 2] );
  1035.     R( c, d, e, a, b, F1, K1, x[ 3] );
  1036.     R( b, c, d, e, a, F1, K1, x[ 4] );
  1037.     R( a, b, c, d, e, F1, K1, x[ 5] );
  1038.     R( e, a, b, c, d, F1, K1, x[ 6] );
  1039.     R( d, e, a, b, c, F1, K1, x[ 7] );
  1040.     R( c, d, e, a, b, F1, K1, x[ 8] );
  1041.     R( b, c, d, e, a, F1, K1, x[ 9] );
  1042.     R( a, b, c, d, e, F1, K1, x[10] );
  1043.     R( e, a, b, c, d, F1, K1, x[11] );
  1044.     R( d, e, a, b, c, F1, K1, x[12] );
  1045.     R( c, d, e, a, b, F1, K1, x[13] );
  1046.     R( b, c, d, e, a, F1, K1, x[14] );
  1047.     R( a, b, c, d, e, F1, K1, x[15] );
  1048.     R( e, a, b, c, d, F1, K1, M(16) );
  1049.     R( d, e, a, b, c, F1, K1, M(17) );
  1050.     R( c, d, e, a, b, F1, K1, M(18) );
  1051.     R( b, c, d, e, a, F1, K1, M(19) );
  1052.     R( a, b, c, d, e, F2, K2, M(20) );
  1053.     R( e, a, b, c, d, F2, K2, M(21) );
  1054.     R( d, e, a, b, c, F2, K2, M(22) );
  1055.     R( c, d, e, a, b, F2, K2, M(23) );
  1056.     R( b, c, d, e, a, F2, K2, M(24) );
  1057.     R( a, b, c, d, e, F2, K2, M(25) );
  1058.     R( e, a, b, c, d, F2, K2, M(26) );
  1059.     R( d, e, a, b, c, F2, K2, M(27) );
  1060.     R( c, d, e, a, b, F2, K2, M(28) );
  1061.     R( b, c, d, e, a, F2, K2, M(29) );
  1062.     R( a, b, c, d, e, F2, K2, M(30) );
  1063.     R( e, a, b, c, d, F2, K2, M(31) );
  1064.     R( d, e, a, b, c, F2, K2, M(32) );
  1065.     R( c, d, e, a, b, F2, K2, M(33) );
  1066.     R( b, c, d, e, a, F2, K2, M(34) );
  1067.     R( a, b, c, d, e, F2, K2, M(35) );
  1068.     R( e, a, b, c, d, F2, K2, M(36) );
  1069.     R( d, e, a, b, c, F2, K2, M(37) );
  1070.     R( c, d, e, a, b, F2, K2, M(38) );
  1071.     R( b, c, d, e, a, F2, K2, M(39) );
  1072.     R( a, b, c, d, e, F3, K3, M(40) );
  1073.     R( e, a, b, c, d, F3, K3, M(41) );
  1074.     R( d, e, a, b, c, F3, K3, M(42) );
  1075.     R( c, d, e, a, b, F3, K3, M(43) );
  1076.     R( b, c, d, e, a, F3, K3, M(44) );
  1077.     R( a, b, c, d, e, F3, K3, M(45) );
  1078.     R( e, a, b, c, d, F3, K3, M(46) );
  1079.     R( d, e, a, b, c, F3, K3, M(47) );
  1080.     R( c, d, e, a, b, F3, K3, M(48) );
  1081.     R( b, c, d, e, a, F3, K3, M(49) );
  1082.     R( a, b, c, d, e, F3, K3, M(50) );
  1083.     R( e, a, b, c, d, F3, K3, M(51) );
  1084.     R( d, e, a, b, c, F3, K3, M(52) );
  1085.     R( c, d, e, a, b, F3, K3, M(53) );
  1086.     R( b, c, d, e, a, F3, K3, M(54) );
  1087.     R( a, b, c, d, e, F3, K3, M(55) );
  1088.     R( e, a, b, c, d, F3, K3, M(56) );
  1089.     R( d, e, a, b, c, F3, K3, M(57) );
  1090.     R( c, d, e, a, b, F3, K3, M(58) );
  1091.     R( b, c, d, e, a, F3, K3, M(59) );
  1092.     R( a, b, c, d, e, F4, K4, M(60) );
  1093.     R( e, a, b, c, d, F4, K4, M(61) );
  1094.     R( d, e, a, b, c, F4, K4, M(62) );
  1095.     R( c, d, e, a, b, F4, K4, M(63) );
  1096.     R( b, c, d, e, a, F4, K4, M(64) );
  1097.     R( a, b, c, d, e, F4, K4, M(65) );
  1098.     R( e, a, b, c, d, F4, K4, M(66) );
  1099.     R( d, e, a, b, c, F4, K4, M(67) );
  1100.     R( c, d, e, a, b, F4, K4, M(68) );
  1101.     R( b, c, d, e, a, F4, K4, M(69) );
  1102.     R( a, b, c, d, e, F4, K4, M(70) );
  1103.     R( e, a, b, c, d, F4, K4, M(71) );
  1104.     R( d, e, a, b, c, F4, K4, M(72) );
  1105.     R( c, d, e, a, b, F4, K4, M(73) );
  1106.     R( b, c, d, e, a, F4, K4, M(74) );
  1107.     R( a, b, c, d, e, F4, K4, M(75) );
  1108.     R( e, a, b, c, d, F4, K4, M(76) );
  1109.     R( d, e, a, b, c, F4, K4, M(77) );
  1110.     R( c, d, e, a, b, F4, K4, M(78) );
  1111.     R( b, c, d, e, a, F4, K4, M(79) );
  1112.  
  1113.     /* update chainig vars */
  1114.     hd->h0 += a;
  1115.     hd->h1 += b;
  1116.     hd->h2 += c;
  1117.     hd->h3 += d;
  1118.     hd->h4 += e;
  1119. }
  1120.  
  1121.  
  1122. /* Update the message digest with the contents
  1123.  * of INBUF with length INLEN.
  1124.  */
  1125. static void
  1126. sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
  1127. {
  1128.     if( hd->count == 64 ) { /* flush the buffer */
  1129.         transform( hd, hd->buf );
  1130.         hd->count = 0;
  1131.         hd->nblocks++;
  1132.     }
  1133.     if( !inbuf )
  1134.         return;
  1135.     if( hd->count ) {
  1136.         for( ; inlen && hd->count < 64; inlen-- )
  1137.             hd->buf[hd->count++] = *inbuf++;
  1138.         sha1_write( hd, NULL, 0 );
  1139.         if( !inlen )
  1140.             return;
  1141.     }
  1142.  
  1143.     while( inlen >= 64 ) {
  1144.         transform( hd, inbuf );
  1145.         hd->count = 0;
  1146.         hd->nblocks++;
  1147.         inlen -= 64;
  1148.         inbuf += 64;
  1149.     }
  1150.     for( ; inlen && hd->count < 64; inlen-- )
  1151.         hd->buf[hd->count++] = *inbuf++;
  1152. }
  1153.  
  1154.  
  1155. /* The routine final terminates the computation and
  1156.  * returns the digest.
  1157.  * The handle is prepared for a new cycle, but adding bytes to the
  1158.  * handle will the destroy the returned buffer.
  1159.  * Returns: 20 bytes representing the digest.
  1160.  */
  1161.  
  1162. static void
  1163. sha1_final(SHA1_CONTEXT *hd)
  1164. {
  1165.     u32 t, msb, lsb;
  1166.     byte *p;
  1167.  
  1168.     sha1_write(hd, NULL, 0); /* flush */;
  1169.  
  1170.     msb = 0;
  1171.     t = hd->nblocks;
  1172.     if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
  1173.         msb++;
  1174.     msb += t >> 26;
  1175.     t = lsb;
  1176.     if( (lsb = t + hd->count) < t ) /* add the count */
  1177.         msb++;
  1178.     t = lsb;
  1179.     if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
  1180.         msb++;
  1181.     msb += t >> 29;
  1182.  
  1183.     if( hd->count < 56 ) { /* enough room */
  1184.         hd->buf[hd->count++] = 0x80; /* pad */
  1185.         while( hd->count < 56 )
  1186.             hd->buf[hd->count++] = 0;  /* pad */
  1187.     }
  1188.     else { /* need one extra block */
  1189.         hd->buf[hd->count++] = 0x80; /* pad character */
  1190.         while( hd->count < 64 )
  1191.             hd->buf[hd->count++] = 0;
  1192.         sha1_write(hd, NULL, 0);  /* flush */;
  1193.         memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
  1194.     }
  1195.     /* append the 64 bit count */
  1196.     hd->buf[56] = msb >> 24;
  1197.     hd->buf[57] = msb >> 16;
  1198.     hd->buf[58] = msb >>  8;
  1199.     hd->buf[59] = msb      ;
  1200.     hd->buf[60] = lsb >> 24;
  1201.     hd->buf[61] = lsb >> 16;
  1202.     hd->buf[62] = lsb >>  8;
  1203.     hd->buf[63] = lsb      ;
  1204.     transform( hd, hd->buf );
  1205.  
  1206.     p = hd->buf;
  1207. #ifdef WORDS_BIGENDIAN
  1208. # define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
  1209. #else /* little endian */
  1210. # define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;         \
  1211.                    *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
  1212. #endif
  1213.     X(0);
  1214.     X(1);
  1215.     X(2);
  1216.     X(3);
  1217.     X(4);
  1218.   #undef X
  1219.  
  1220. }
  1221.  
  1222. static byte *
  1223. sha1_read( SHA1_CONTEXT *hd )
  1224. {
  1225.     return hd->buf;
  1226. }
  1227.  
  1228. /****************
  1229.  * Return some information about the algorithm.  We need algo here to
  1230.  * distinguish different flavors of the algorithm.
  1231.  * Returns: A pointer to string describing the algorithm or NULL if
  1232.  *          the ALGO is invalid.
  1233.  */
  1234. const char *
  1235. sha1_get_info( int algo, size_t *contextsize,
  1236.                byte **r_asnoid, int *r_asnlen, int *r_mdlen,
  1237.                void (**r_init)( void *c ),
  1238.                void (**r_write)( void *c, byte *buf, size_t nbytes ),
  1239.                void (**r_final)( void *c ),
  1240.                byte *(**r_read)( void *c )
  1241.              )
  1242. {
  1243.     static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */
  1244.                     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
  1245.                       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
  1246.     if( algo != 2 )
  1247.         return NULL;
  1248.  
  1249.     *contextsize = sizeof(SHA1_CONTEXT);
  1250.     *r_asnoid = asn;
  1251.     *r_asnlen = DIM(asn);
  1252.     *r_mdlen = 20;
  1253.     *r_init  = (void (*)(void *))sha1_init;
  1254.     *r_write = (void (*)(void *, byte*, size_t))sha1_write;
  1255.     *r_final = (void (*)(void *))sha1_final;
  1256.     *r_read  = (byte *(*)(void *))sha1_read;
  1257.  
  1258.     return "SHA1";
  1259. }
  1260.  
  1261. /*
  1262.  SHA1 implementation ends here
  1263.  -----8<-----------------------------------------------------------------------
  1264. */
RAW Paste Data
Pastebin PRO Autumn Special!
Get 40% OFF on Pastebin PRO accounts!
Top