home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / prbfish.c < prev    next >
C/C++ Source or Header  |  2001-03-09  |  11KB  |  295 lines

  1. /* -*-C-*-
  2.  
  3. $Id: prbfish.c,v 1.12 2001/03/09 16:12:53 cph Exp $
  4.  
  5. Copyright (c) 1997-2001 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. /* Interface to Blowfish library */
  23.  
  24. #include "scheme.h"
  25. #include "prims.h"
  26.  
  27. #if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_BLOWFISH_H)
  28. #  include <openssl/blowfish.h>
  29. #else
  30. #  ifdef HAVE_BLOWFISH_H
  31. #    include <blowfish.h>
  32. #  endif
  33. #endif
  34.  
  35. /* This interface uses the Blowfish library from SSLeay.  */
  36.  
  37. DEFINE_PRIMITIVE ("BLOWFISH-SET-KEY", Prim_blowfish_set_key, 1, 1,
  38.   "(STRING)\n\
  39. Generate a Blowfish key from STRING.\n\
  40. STRING must be 72 bytes or less in length.\n\
  41. For text-string keys, use MD5 on the text, and pass the digest here.")
  42. {
  43.   SCHEME_OBJECT string;
  44.   SCHEME_OBJECT result;
  45.   PRIMITIVE_HEADER (1);
  46.  
  47.   CHECK_ARG (1, STRING_P);
  48.   string = (ARG_REF (1));
  49.   if ((STRING_LENGTH (string)) > 72)
  50.     error_bad_range_arg (1);
  51.   result = (allocate_string (sizeof (BF_KEY)));
  52.   BF_set_key (((BF_KEY *) (STRING_LOC (result, 0))),
  53.           (STRING_LENGTH (string)),
  54.           (STRING_LOC (string, 0)));
  55.   PRIMITIVE_RETURN (result);
  56. }
  57.  
  58. static BF_KEY *
  59. DEFUN (key_arg, (arg), unsigned int arg)
  60. {
  61.   CHECK_ARG (arg, STRING_P);
  62.   if ((STRING_LENGTH (ARG_REF (arg))) != (sizeof (BF_KEY)))
  63.     error_bad_range_arg (arg);
  64.   return ((BF_KEY *) (STRING_LOC ((ARG_REF (arg)), 0)));
  65. }
  66.  
  67. static unsigned char *
  68. DEFUN (init_vector_arg, (arg), unsigned int arg)
  69. {
  70.   CHECK_ARG (arg, STRING_P);
  71.   if ((STRING_LENGTH (ARG_REF (arg))) != 8)
  72.     error_bad_range_arg (arg);
  73.   return (STRING_LOC ((ARG_REF (arg)), 0));
  74. }
  75.  
  76. DEFINE_PRIMITIVE ("BLOWFISH-ECB", Prim_blowfish_ecb, 4, 4,
  77.   "(INPUT OUTPUT KEY-VECTOR ENCRYPT?)\n\
  78. Apply Blowfish in Electronic Code Book mode.\n\
  79. INPUT is an 8-byte string.\n\
  80. OUTPUT is an 8-byte string.\n\
  81. KEY is a Blowfish key.\n\
  82. ENCRYPT? says whether to encrypt (#T) or decrypt (#F).")
  83. {
  84.   SCHEME_OBJECT input_text;
  85.   SCHEME_OBJECT output_text;
  86.   PRIMITIVE_HEADER (4);
  87.  
  88.   CHECK_ARG (1, STRING_P);
  89.   input_text = (ARG_REF (1));
  90.   if ((STRING_LENGTH (input_text)) != 8)
  91.     error_bad_range_arg (1);
  92.   CHECK_ARG (2, STRING_P);
  93.   output_text = (ARG_REF (2));
  94.   if ((STRING_LENGTH (output_text)) != 8)
  95.     error_bad_range_arg (2);
  96.   BF_ecb_encrypt ((STRING_LOC (input_text, 0)),
  97.           (STRING_LOC (output_text, 0)),
  98.           (key_arg (3)),
  99.           ((BOOLEAN_ARG (4)) ? BF_ENCRYPT : BF_DECRYPT));
  100.   PRIMITIVE_RETURN (UNSPECIFIC);
  101. }
  102.  
  103. DEFINE_PRIMITIVE ("BLOWFISH-CBC-V2", Prim_blowfish_cbc, 5, 5,
  104.   "(INPUT OUTPUT KEY INIT-VECTOR ENCRYPT?)\n\
  105. Apply Blowfish in Cipher Block Chaining mode.\n\
  106. INPUT is a string whose length is a multiple of 8 bytes.\n\
  107. OUTPUT is a string whose length is the same as INPUT.\n\
  108. KEY is a Blowfish key.\n\
  109. INIT-VECTOR is an 8-byte string; it is modified after each call.\n\
  110.   The value from any call may be passed in to a later call.\n\
  111. ENCRYPT? says whether to encrypt (#T) or decrypt (#F).")
  112. {
  113.   SCHEME_OBJECT input_text;
  114.   SCHEME_OBJECT output_text;
  115.   PRIMITIVE_HEADER (5);
  116.  
  117.   CHECK_ARG (1, STRING_P);
  118.   input_text = (ARG_REF (1));
  119.   if (((STRING_LENGTH (input_text)) % 8) != 0)
  120.     error_bad_range_arg (1);
  121.   CHECK_ARG (2, STRING_P);
  122.   output_text = (ARG_REF (2));
  123.   if ((output_text == input_text)
  124.       || ((STRING_LENGTH (output_text)) != (STRING_LENGTH (input_text))))
  125.     error_bad_range_arg (2);
  126.   BF_cbc_encrypt ((STRING_LOC (input_text, 0)),
  127.           (STRING_LOC (output_text, 0)),
  128.           (STRING_LENGTH (input_text)),
  129.           (key_arg (3)),
  130.           (init_vector_arg (4)),
  131.           ((BOOLEAN_ARG (5)) ? BF_ENCRYPT : BF_DECRYPT));
  132.   PRIMITIVE_RETURN (UNSPECIFIC);
  133. }
  134.  
  135. DEFINE_PRIMITIVE ("BLOWFISH-CFB64-SUBSTRING-V2", Prim_blowfish_cfb64_substring, 9, 9,
  136.   "(INPUT ISTART IEND OUTPUT OSTART KEY INIT-VECTOR NUM ENCRYPT?)\n\
  137. Apply Blowfish in Cipher Feed-Back mode.\n\
  138. (INPUT,ISTART,IEND) is an arbitrary substring.\n\
  139. OUTPUT is a string as large as the input substring.\n\
  140. OSTART says where to start writing to the output string.\n\
  141. KEY is a Blowfish key.\n\
  142. INIT-VECTOR is an 8-byte string; it is modified after each call.\n\
  143.   The value from any call may be passed in to a later call.\n\
  144.   The initial value must be unique for each message/key pair.\n\
  145. NUM is a digit from 0 to 7 inclusive; it is the low 3 bits of the\n\
  146.   number of bytes that have previously been processed in this stream.\n\
  147. ENCRYPT? says whether to encrypt (#T) or decrypt (#F).\n\
  148. Returned value is the new value of NUM.")
  149. {
  150.   SCHEME_OBJECT input_text;
  151.   unsigned long istart;
  152.   unsigned long iend;
  153.   unsigned long ilen;
  154.   SCHEME_OBJECT output_text;
  155.   unsigned long ostart;
  156.   int num;
  157.   PRIMITIVE_HEADER (9);
  158.  
  159.   CHECK_ARG (1, STRING_P);
  160.   input_text = (ARG_REF (1));
  161.   {
  162.     unsigned long l = (STRING_LENGTH (input_text));
  163.     istart = (arg_ulong_index_integer (2, l));
  164.     iend = (arg_integer_in_range (3, istart, (l + 1)));
  165.   }
  166.   ilen = (iend - istart);
  167.   CHECK_ARG (4, STRING_P);
  168.   output_text = (ARG_REF (4));
  169.   ostart = (arg_ulong_index_integer (5, (STRING_LENGTH (output_text))));
  170.   if ((output_text == input_text)
  171.       && (ostart < iend)
  172.       && (istart < (ostart + ilen)))
  173.     error_bad_range_arg (4);
  174.   num = (arg_index_integer (8, 8));
  175.   BF_cfb64_encrypt ((STRING_LOC (input_text, istart)),
  176.             (STRING_LOC (output_text, ostart)),
  177.             ilen,
  178.             (key_arg (6)),
  179.             (init_vector_arg (7)),
  180.             (&num),
  181.             ((BOOLEAN_ARG (9)) ? BF_ENCRYPT : BF_DECRYPT));
  182.   PRIMITIVE_RETURN (long_to_integer (num));
  183. }
  184.  
  185. DEFINE_PRIMITIVE ("BLOWFISH-OFB64-SUBSTRING", Prim_blowfish_ofb64_substring, 8, 8,
  186.   "(INPUT ISTART IEND OUTPUT OSTART KEY INIT-VECTOR NUM)\n\
  187. Apply Blowfish in Output Feed-Back mode.\n\
  188. (INPUT,ISTART,IEND) is an arbitrary substring.\n\
  189. OUTPUT is a string as large as the input substring.\n\
  190. OSTART says where to start writing to the output string.\n\
  191. KEY is a Blowfish key.\n\
  192. INIT-VECTOR is an 8-byte string; it is modified after each call.\n\
  193.   The value from any call may be passed in to a later call.\n\
  194.   The initial value must be unique for each message/key pair.\n\
  195. NUM is a digit from 0 to 7 inclusive; it is the low 3 bits of the\n\
  196.   number of bytes that have previously been processed in this stream.\n\
  197. Returned value is the new value of NUM.")
  198. {
  199.   SCHEME_OBJECT input_text;
  200.   unsigned long istart;
  201.   unsigned long iend;
  202.   unsigned long ilen;
  203.   SCHEME_OBJECT output_text;
  204.   unsigned long ostart;
  205.   int num;
  206.   PRIMITIVE_HEADER (8);
  207.  
  208.   CHECK_ARG (1, STRING_P);
  209.   input_text = (ARG_REF (1));
  210.   {
  211.     unsigned long l = (STRING_LENGTH (input_text));
  212.     istart = (arg_ulong_index_integer (2, l));
  213.     iend = (arg_integer_in_range (3, istart, (l + 1)));
  214.   }
  215.   ilen = (iend - istart);
  216.   CHECK_ARG (4, STRING_P);
  217.   output_text = (ARG_REF (4));
  218.   ostart = (arg_ulong_index_integer (5, (STRING_LENGTH (output_text))));
  219.   if ((output_text == input_text)
  220.       && (ostart < iend)
  221.       && (istart < (ostart + ilen)))
  222.     error_bad_range_arg (4);
  223.   num = (arg_index_integer (8, 8));
  224.   BF_ofb64_encrypt ((STRING_LOC (input_text, istart)),
  225.             (STRING_LOC (output_text, ostart)),
  226.             ilen,
  227.             (key_arg (6)),
  228.             (init_vector_arg (7)),
  229.             (&num));
  230.   PRIMITIVE_RETURN (long_to_integer (num));
  231. }
  232.  
  233. #ifdef COMPILE_AS_MODULE
  234.  
  235. char *
  236. DEFUN_VOID (dload_initialize_file)
  237. {
  238.   declare_primitive
  239.     ("BLOWFISH-SET-KEY", Prim_blowfish_set_key, 1, 1,
  240.      "(STRING)\n\
  241. Generate a Blowfish key from STRING.\n\
  242. STRING must be 72 bytes or less in length.\n\
  243. For text-string keys, use MD5 on the text, and pass the digest here.");
  244.   declare_primitive
  245.     ("BLOWFISH-ECB", Prim_blowfish_ecb, 4, 4,
  246.      "(INPUT OUTPUT KEY-VECTOR ENCRYPT?)\n\
  247. Apply Blowfish in Electronic Code Book mode.\n\
  248. INPUT is an 8-byte string.\n\
  249. OUTPUT is an 8-byte string.\n\
  250. KEY is a Blowfish key.\n\
  251. ENCRYPT? says whether to encrypt (#T) or decrypt (#F).");
  252.   declare_primitive
  253.     ("BLOWFISH-CBC-V2", Prim_blowfish_cbc, 5, 5,
  254.      "(INPUT OUTPUT KEY INIT-VECTOR ENCRYPT?)\n\
  255. Apply Blowfish in Cipher Block Chaining mode.\n\
  256. INPUT is a string whose length is a multiple of 8 bytes.\n\
  257. OUTPUT is a string whose length is the same as INPUT.\n\
  258. KEY is a Blowfish key.\n\
  259. INIT-VECTOR is an 8-byte string; it is modified after each call.\n\
  260.   The value from any call may be passed in to a later call.\n\
  261. ENCRYPT? says whether to encrypt (#T) or decrypt (#F).");
  262.   declare_primitive
  263.     ("BLOWFISH-CFB64-SUBSTRING-V2", Prim_blowfish_cfb64_substring, 9, 9,
  264.      "(INPUT ISTART IEND OUTPUT OSTART KEY INIT-VECTOR NUM ENCRYPT?)\n\
  265. Apply Blowfish in Cipher Feed-Back mode.\n\
  266. \(INPUT,ISTART,IEND) is an arbitrary substring.\n\
  267. OUTPUT is a string as large as the input substring.\n\
  268. OSTART says where to start writing to the output string.\n\
  269. KEY is a Blowfish key.\n\
  270. INIT-VECTOR is an 8-byte string; it is modified after each call.\n\
  271.   The value from any call may be passed in to a later call.\n\
  272.   The initial value must be unique for each message/key pair.\n\
  273. NUM is a digit from 0 to 7 inclusive; it is the low 3 bits of the\n\
  274.   number of bytes that have previously been processed in this stream.\n\
  275. ENCRYPT? says whether to encrypt (#T) or decrypt (#F).\n\
  276. Returned value is the new value of NUM.");
  277.   declare_primitive
  278.     ("BLOWFISH-OFB64-SUBSTRING", Prim_blowfish_ofb64_substring, 8, 8,
  279.      "(INPUT ISTART IEND OUTPUT OSTART KEY INIT-VECTOR NUM)\n\
  280. Apply Blowfish in Output Feed-Back mode.\n\
  281. (INPUT,ISTART,IEND) is an arbitrary substring.\n\
  282. OUTPUT is a string as large as the input substring.\n\
  283. OSTART says where to start writing to the output string.\n\
  284. KEY is a Blowfish key.\n\
  285. INIT-VECTOR is an 8-byte string; it is modified after each call.\n\
  286.   The value from any call may be passed in to a later call.\n\
  287.   The initial value must be unique for each message/key pair.\n\
  288. NUM is a digit from 0 to 7 inclusive; it is the low 3 bits of the\n\
  289.   number of bytes that have previously been processed in this stream.\n\
  290. Returned value is the new value of NUM.");
  291.   return "#prbfish";
  292. }
  293.  
  294. #endif /* COMPILE_AS_MODULE */
  295.