"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/lib/mcrypt.c" (8 Sep 2002, 6268 Bytes) of package /linux/privat/old/libmcrypt-2.5.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mcrypt.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) 1998,1999,2000 Nikos Mavroyanopoulos
    3  * 
    4  * This library is free software; you can redistribute it and/or modify it 
    5  * under the terms of the GNU Library General Public License as published 
    6  * by the Free Software Foundation; either version 2 of the License, or 
    7  * (at your option) any later version.
    8  *
    9  * This library is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12  * Library General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU Library General Public
   15  * License along with this library; if not, write to the
   16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17  * Boston, MA 02111-1307, USA.
   18  */
   19 
   20 /* $Id: mcrypt.c,v 1.19 2002/07/06 10:18:18 nmav Exp $ */
   21 
   22 /* Changed by Steve Underwood 1999/12/10 to allow an arbitrary number of 
   23  * streams of encryption. Currently the resulting code is probably not
   24  * thread safe, but as far as I could tell the previous code wasn't
   25  * either. This version has brute force locking in a lot of places, but
   26  * it has not been tested in a multi-threaded manner.
   27  * The key locking issue is that the table of encryption streams could
   28  * be moved when it is extended. Any address pre-calculated, or in
   29  * calculation at the time of the reallocation would be screwed.
   30  * This won't happen often, but requires lots of locks - PITA! 
   31  */
   32 
   33 /* Changed again at 1999/12/15 to correct the thread safeness. Now it
   34  * seems to be thread safe. Brute force locking was removed and
   35  * locks per thread were introduced. 
   36  *                      --nikos
   37  */
   38 
   39 /* The above comments are too old! */
   40 
   41 #ifndef LIBDEFS_H
   42 #define LIBDEFS_H
   43 #include <libdefs.h>
   44 #endif
   45 #include <bzero.h>
   46 #include <xmemory.h>
   47 #include <mcrypt_internal.h>
   48 
   49 #if 0
   50 static int preloaded_symbols = 0;
   51 #endif
   52 
   53 static int internal_end_mcrypt(MCRYPT td);
   54 
   55 static int internal_init_mcrypt(MCRYPT td, const void *key, int lenofkey, const void *IV)
   56 {
   57     int *sizes = NULL;
   58     int num_of_sizes, i, ok = 0;
   59     int key_size = mcrypt_enc_get_key_size(td);
   60 
   61     if (lenofkey > key_size || lenofkey==0) {
   62         return MCRYPT_KEY_LEN_ERROR;    /* error */ 
   63     }
   64     
   65     sizes = mcrypt_enc_get_supported_key_sizes(td, &num_of_sizes);
   66     if (sizes != NULL) {
   67         for (i = 0; i < num_of_sizes; i++) {
   68             if (lenofkey == sizes[i]) {
   69                 ok = 1;
   70                 break;
   71             }
   72         }
   73     } else {        /* sizes==NULL */
   74         if (num_of_sizes == 0
   75             && lenofkey <= mcrypt_enc_get_key_size(td))
   76             ok = 1;
   77     }
   78 
   79 
   80     if (ok == 0) { /* not supported key size */
   81         key_size = mcrypt_enc_get_key_size(td);
   82         if (sizes != NULL) {
   83             for (i = 0; i < num_of_sizes; i++) {
   84                 if (lenofkey <= sizes[i]) {
   85                     key_size = sizes[i];
   86                     break;
   87                 }
   88             }
   89         } else { /* well every key size is supported! */
   90             key_size = lenofkey;
   91         }
   92     } else {
   93         key_size = lenofkey;
   94     }
   95     free(sizes);
   96 
   97     td->keyword_given = mxcalloc(1, mcrypt_enc_get_key_size(td));
   98     if (td->keyword_given==NULL) return MCRYPT_MEMORY_ALLOCATION_ERROR; 
   99     
  100     memmove(td->keyword_given, key, lenofkey);
  101     i = mcrypt_get_size(td);
  102     td->akey = mxcalloc(1, i);
  103     if (td->akey==NULL) {
  104         free(td->keyword_given);
  105         return MCRYPT_MEMORY_ALLOCATION_ERROR;
  106     }
  107     i = mcrypt_mode_get_size(td);
  108     if (i > 0) {
  109         td->abuf = mxcalloc(1, i);
  110         if (td->abuf==NULL) {
  111             free(td->keyword_given);
  112             free(td->akey);
  113             return MCRYPT_MEMORY_ALLOCATION_ERROR;
  114         }
  115     }
  116     ok = init_mcrypt(td, td->abuf, key, key_size, IV);
  117     if (ok!=0) {
  118         free(td->keyword_given);
  119         free(td->akey);
  120         free(td->abuf);
  121         return MCRYPT_UNKNOWN_ERROR; /* algorithm error */
  122     }
  123 
  124     ok = mcrypt_set_key(td,
  125                (void *) td->akey,
  126                (void *) td->keyword_given,
  127                key_size, IV, IV!=NULL ? mcrypt_enc_get_iv_size(td) : 0);
  128 
  129     if (ok!=0) {
  130         internal_end_mcrypt(td);
  131         return MCRYPT_UNKNOWN_ERROR; /* algorithm error */
  132     }
  133 
  134     return 0;
  135 }
  136 
  137 static int internal_end_mcrypt(MCRYPT td)
  138 {
  139     mxfree(td->keyword_given, mcrypt_enc_get_key_size(td));
  140     td->keyword_given = NULL;
  141 
  142     mxfree(td->akey, mcrypt_get_size(td));
  143     td->akey = NULL;
  144 
  145     end_mcrypt(td, td->abuf);
  146     if (td->abuf!=NULL) mxfree(td->abuf, mcrypt_mode_get_size(td));
  147     td->abuf = NULL;
  148 
  149     return 0;
  150 }
  151 
  152 /* Generic - High level functions */
  153 
  154 WIN32DLL_DEFINE
  155 int mcrypt_generic_init(const MCRYPT td, const void *key, int lenofkey, const void *IV)
  156 {
  157     return internal_init_mcrypt(td, key, lenofkey, IV);
  158 }
  159 
  160 WIN32DLL_DEFINE
  161 int mcrypt_generic(MCRYPT td, void *plaintext, int len)
  162 {
  163     int x;
  164 
  165     x = mcrypt(td, td->abuf, plaintext, len);
  166     return x;
  167 }
  168 
  169 WIN32DLL_DEFINE
  170 int mdecrypt_generic(MCRYPT td, void *ciphertext, int len)
  171 {
  172     int x;
  173     x = mdecrypt(td, td->abuf, ciphertext, len);
  174     return x;
  175 }
  176 
  177 WIN32DLL_DEFINE
  178 int mcrypt_generic_end( MCRYPT td)
  179 {
  180     if (td==NULL) return MCRYPT_UNKNOWN_ERROR;
  181 
  182     if (td->keyword_given!=NULL)
  183         internal_end_mcrypt(td);
  184     mcrypt_module_close(td);
  185     return 0;
  186 }
  187 
  188 WIN32DLL_DEFINE
  189 int mcrypt_generic_deinit( MCRYPT td)
  190 {
  191     if (td==NULL || td->keyword_given==NULL) return MCRYPT_UNKNOWN_ERROR;
  192     
  193     internal_end_mcrypt(td);
  194     return 0;
  195 }
  196 
  197 WIN32DLL_DEFINE
  198 void mcrypt_perror(int err)
  199 {
  200 
  201     switch (err) {
  202     case MCRYPT_UNKNOWN_ERROR:
  203         fprintf(stderr, "Unknown error.\n");
  204         break;
  205     case MCRYPT_ALGORITHM_MODE_INCOMPATIBILITY:
  206         fprintf(stderr,
  207             "Algorithm incompatible with this mode.\n");
  208         break;
  209     case MCRYPT_KEY_LEN_ERROR:
  210         fprintf(stderr, "Key length is not legal.\n");
  211         break;
  212     case MCRYPT_MEMORY_ALLOCATION_ERROR:
  213         fprintf(stderr, "Memory allocation failed.\n");
  214         break;
  215     case MCRYPT_UNKNOWN_MODE:
  216         fprintf(stderr, "Unknown mode.\n");
  217         break;
  218     case MCRYPT_UNKNOWN_ALGORITHM:
  219         fprintf(stderr, "Unknown algorithm.\n");
  220         break;
  221 
  222     }
  223     return;
  224 }
  225 
  226 WIN32DLL_DEFINE
  227 const char* mcrypt_strerror(int err)
  228 {
  229 
  230     switch (err) {
  231     case MCRYPT_UNKNOWN_ERROR:
  232         return "Unknown error.\n";
  233         break;
  234     case MCRYPT_ALGORITHM_MODE_INCOMPATIBILITY:
  235         return  "Algorithm incompatible with this mode.\n";
  236         break;
  237     case MCRYPT_KEY_LEN_ERROR:
  238         return "Key length is not legal.\n";
  239         break;
  240     case MCRYPT_MEMORY_ALLOCATION_ERROR:
  241         return "Memory allocation failed.\n";
  242         break;
  243     case MCRYPT_UNKNOWN_MODE:
  244         return "Unknown mode.\n";
  245         break;
  246     case MCRYPT_UNKNOWN_ALGORITHM:
  247         return "Unknown algorithm.\n";
  248         break;
  249 
  250     }
  251     return NULL;
  252 }
  253 
  254 WIN32DLL_DEFINE
  255 void mcrypt_free(void *ptr)
  256 {
  257     free(ptr);
  258 }