/* ***************************************************************** *
 * Copyright 1998 International Business Machines Corporation. All   *
 * Rights Reserved.                                                  *
 *                                                                   *
 * Please read this carefully.  Your use of this reference           *
 * implementation of certain of the IETF public-key infrastructure   *
 * specifications ("Software") indicates your acceptance of the      *
 * following.  If you do not agree to the following, do not install  *
 * or use any of the Software.                                       *
 *                                                                   *
 * Permission to use, reproduce, distribute and create derivative    *
 * works from the Software ("Software Derivative Works"), and to     *
 * distribute such Software Derivative Works is hereby granted to    *
 * you by International Business Machines Corporation ("IBM").  This *
 * permission includes a license under the patents of IBM that are   *
 * necessarily infringed by your use of the Software as provided by  *
 * IBM.                                                              *
 *                                                                   *
 * IBM licenses the Software to you on an "AS IS" basis, without     *
 * warranty of any kind.  IBM HEREBY EXPRESSLY DISCLAIMS ALL         *
 * WARRANTIES OR CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF       *
 * MERCHANTABILITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR    *
 * PURPOSE.  You are solely responsible for determining the          *
 * appropriateness of using this Software and assume all risks       *
 * associated with the use of this Software, including but not       *
 * limited to the risks of program errors, damage to or loss of      *
 * data, programs or equipment, and unavailability or interruption   *
 * of operations.                                                    *
 *                                                                   *
 * IBM WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, *
 * INCIDENTAL, OR  INDIRECT DAMAGES OR FOR ANY ECONOMIC              *
 * CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN   *
 * IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  IBM  *
 * will not be liable for the loss of, or damage to, your records or *
 * data, or any damages claimed by you based on a third party claim. *
 *                                                                   *
 * IBM wishes to obtain your feedback to assist in improving the     *
 * Software.  You grant IBM a world-wide, royalty-free right to use, *
 * copy, distribute, sublicense and prepare derivative works based   *
 * upon any feedback, including materials, error corrections,        *
 * Software Derivatives, enhancements, suggestions and the like that *
 * you provide to IBM relating to the Software (this does not        *
 * include products for which you charge a royalty and distribute to *
 * IBM under other terms and conditions).                            *
 *                                                                   *
 * You agree to distribute the Software and any Software Derivatives *
 * under a license agreement that: 1) is sufficient to notify all    *
 * licensees of the Software and Software Derivatives that IBM       *
 * assumes no liability for any claim that may arise regarding the   *
 * Software or Software Derivatives, and 2) that disclaims all       *
 * warranties, both express and implied, from IBM regarding the      *
 * Software and Software Derivatives.  (If you include this          *
 * Agreement with any distribution of the Software or Software       *
 * Derivatives you will have met this requirement.)  You agree that  *
 * you will not delete any copyright notices in the Software.        *
 *                                                                   *
 * This Agreement is the exclusive statement of your rights in the   *
 * Software as provided by IBM.   Except for the rights granted to   *
 * you in the second paragraph above, You are not granted any other  *
 * patent rights, including but not limited to the right to make     *
 * combinations of the Software with products that infringe IBM      *
 * patents. You agree to comply with all applicable laws and         *
 * regulations, including all export and import laws and regulation. *
 * This Agreement is governed by the laws of the State of New York.  *
 * This Agreement supersedes all other communications,               *
 * understandings or agreements we may have had prior to this        *
 * Agreement.                                                        *
 * ***************************************************************** */


//------------------------------------------------------------
// includes
//------------------------------------------------------------

#include <assert.h>
#include <limits.h>
#include <iostream>
#include <set>
#include <map>
#include "dsa.h"
#include "jkl.h"
#include "jklutil.h"

// using Microsoft's Standard Template Library
// Porting note: not all compilers support namespaces

using namespace std;


// temporary resting place of useful constants

// Known CDSA CSP addins

static CSSM_GUID IBM_CYLINK_CSP_GUID = { 0xba047041, 0x31f4, 0x11d2, { 0xb1, 0xd4, 0x0, 0x20, 0x35, 0x68, 0xb, 0x0 } };
static CSSM_GUID IBM_BSAFE_CSP_GUID  = { 0xdda0c1e0, 0x7b73, 0x11d0, { 0x8e, 0x0c, 0x0, 0x04, 0xac, 0x60, 0x2b, 0x18 } };
static CSSM_GUID JONAH_TP_GUID       = { 0x7e25d1e0, 0x2658, 0x11d2, { 0x99, 0xbd, 0x0, 0x4, 0xac, 0xe8, 0x48, 0x5b } };

// supported signature algorithms

static unsigned long md2WithRSAEncryption_val[7]       = {1,2,840,113549,1,1,2};
static unsigned long md5WithRSAEncryption_val[7]       = {1,2,840,113549,1,1,4};
static unsigned long sha1WithRSAEncryption_val[7]      = {1,2,840,113549,1,1,5};
static unsigned long dsaWithSHA1_val[6]                = {1,2,840,10040,4,3};

// supported public key algorithms (dsa_alt used by BSAFE for DSA public key)

static unsigned long rsaEncryption_val[7]              = {1,2,840,113549,1,1,1};
static unsigned long dsa_val[6]                        = {1,2,840,10040,4,1};
static unsigned long dsa_alt_val[6]                    = {1,3,14,3,2,12};

// temporary resting place of useful constants


//------------------------------------------------------------
// class: GuidWrapper
//------------------------------------------------------------

struct GuidWrapper {

   // attributes

   CSSM_GUID guid;

   // methods

   GuidWrapper() 
   {
      guid.Data1    = 0;
      guid.Data2    = 0;
      guid.Data3    = 0;
      guid.Data4[0] = 0;
      guid.Data4[1] = 0;
      guid.Data4[2] = 0;
      guid.Data4[3] = 0;
      guid.Data4[4] = 0;
      guid.Data4[5] = 0;
      guid.Data4[6] = 0;
      guid.Data4[7] = 0;
   }

   GuidWrapper(const CSSM_GUID& toBeCopied)
   : guid(toBeCopied)
   {
   }

   // comparators

   bool operator==(const GuidWrapper& rhs) const
    {
      return ( guid.Data1     == rhs.guid.Data1      &&
               guid.Data2     == rhs.guid.Data2      &&
               guid.Data3     == rhs.guid.Data3      &&
               guid.Data4[0]  == rhs.guid.Data4[0]   &&
               guid.Data4[1]  == rhs.guid.Data4[1]   &&
               guid.Data4[2]  == rhs.guid.Data4[2]   &&
               guid.Data4[3]  == rhs.guid.Data4[3]   &&
               guid.Data4[4]  == rhs.guid.Data4[4]   &&
               guid.Data4[5]  == rhs.guid.Data4[5]   &&
               guid.Data4[6]  == rhs.guid.Data4[6]   &&
               guid.Data4[7]  == rhs.guid.Data4[7]   );
    }

  bool operator<(const GuidWrapper& rhs) const
    {
      return ( sum() < rhs.sum() );
    }

  // < operator arbitrary: define this function to 
  // impose on "order" on CSSM_GUID structures

  uint32 sum() const
    {
      uint32 sum;
      sum =  guid.Data1;
      sum =+ guid.Data2;
      sum =+ guid.Data3;
      for (int i = 0; i < 8; i++) { sum =+ guid.Data4[i]; }
      return sum;
    }
};


//------------------------------------------------------------
// Types
//------------------------------------------------------------

typedef set<uint32, less<uint32> > AlgorithmSet;
typedef set<uint32, less<uint32> >::iterator AlgorithmSetIter;

typedef map<uint32, CSSM_CSP_HANDLE, less<uint32> > CachedAlgorithmMap;
typedef map<uint32, CSSM_CSP_HANDLE, less<uint32> >::iterator CachedAlgorithmMapIter;


//------------------------------------------------------------
// class: CSPAttachProperty
//------------------------------------------------------------

struct CSPAttachProperty
{
   // attributes

   CSSM_CSP_HANDLE cspHandle;
   AlgorithmSet algorithmSet;

   // methods

   CSPAttachProperty(void)
   :  cspHandle(0)
   {
   }

   CSPAttachProperty(const CSPAttachProperty& toBeCopied)
   :  cspHandle(toBeCopied.cspHandle),
      algorithmSet(toBeCopied.algorithmSet)
   {
   }

   // operators

   CSPAttachProperty& operator=(const CSPAttachProperty& rhs)
   {
      if (this != &rhs)
      {
         cspHandle = rhs.cspHandle;
         algorithmSet = rhs.algorithmSet;
      }
      return *this;
   }

   // comparators

  bool operator==(const CSPAttachProperty& rhs) const
    {
      return (cspHandle == rhs.cspHandle);
    }

  bool operator<(const CSPAttachProperty& rhs) const
    {
      return (cspHandle < rhs.cspHandle);
    }
};


//------------------------------------------------------------
// Types
//------------------------------------------------------------

typedef map<GuidWrapper, CSPAttachProperty, less<GuidWrapper> > CSPAttachMap;
typedef map<GuidWrapper, CSPAttachProperty, less<GuidWrapper> >::iterator CSPAttachMapIter;


//------------------------------------------------------------
// static data
//------------------------------------------------------------

static CSPAttachMap gCSPAttachMap;

static CachedAlgorithmMap gCachedAlgorithmMap;


//------------------------------------------------------------
// useful constants
//------------------------------------------------------------

// create BSAFE-compatible DSA OID in SubjectPublicKeyInfo and PrivateKeyInfo?
//#define BSAFE_COMPATIBILITY 1

// memory management

CSSM_MEMORY_FUNCS gMemoryFuncs = {0,0,0,0,0};


//*****************************************************************************
//
// module initialization and management
//
//*****************************************************************************


//------------------------------------------------------------
// function: JKL_SetPreferredCSP
//------------------------------------------------------------

uint32 
JKL_SetPreferredCSP(const CSSM_GUID& cssmGUID)
{
   CSPAttachMapIter i;
   AlgorithmSetIter j;

   // locate GUID in attach map

   GuidWrapper key(cssmGUID);
   i = gCSPAttachMap.find(key);

   if (i == gCSPAttachMap.end())
      return CSSM_CSP_OPERATION_UNSUPPORTED;

   // update cache map

   for (j = (*i).second.algorithmSet.begin(); j != (*i).second.algorithmSet.end(); j++)
   {
      uint32 algorithm = (*j);
      gCachedAlgorithmMap[algorithm] = (*i).second.cspHandle;
   }

   return 0;
}


//------------------------------------------------------------
// function: JKL_AlgorithmIsSupported
//------------------------------------------------------------

bool
JKL_AlgorithmIsSupported(const CSSM_GUID& cssmGUID, 
                         uint32 algorithmID)
{
   // locate GUID in attach map

   GuidWrapper key(cssmGUID);
   CSPAttachMapIter i = gCSPAttachMap.find(key);

   // is this a valid GUID?

   if (i == gCSPAttachMap.end())
      return false;

   // is algorithm in algorithmSet?

   AlgorithmSetIter j = (*i).second.algorithmSet.find(algorithmID);
   if (j == (*i).second.algorithmSet.end())
      return false;

   return true;
}


//------------------------------------------------------------
// function: JKL_SetPreferredCSP
//------------------------------------------------------------

uint32 
JKL_SetPreferredCSP(const CSSM_GUID& cssmGUID, 
                    uint32 algorithmID)
{
   if ( JKL_AlgorithmIsSupported(cssmGUID, algorithmID) )
   {
      GuidWrapper key(cssmGUID);
      CSPAttachMapIter i = gCSPAttachMap.find(key);
      gCachedAlgorithmMap[algorithmID] = (*i).second.cspHandle;
      return 0;
   }
   else
   {
      return CSSM_CSP_OPERATION_UNSUPPORTED;
   }
}


//------------------------------------------------------------
// function: JKL_GetPreferredCSP
//------------------------------------------------------------

uint32 
JKL_GetPreferredCSP(CSSM_GUID& cssmGUID, 
                    uint32 algorithmID)
{
   CachedAlgorithmMapIter i = gCachedAlgorithmMap.find(algorithmID);
   if (i != gCachedAlgorithmMap.end())
   {
      cssmGUID = * CSSM_GetModuleGUIDFromHandle( (*i).second );
      return 0;
   }
   else
   {
      return CSSM_CSP_OPERATION_UNSUPPORTED;
   }
}


//------------------------------------------------------------
// function: JKL_PopulateCachedAlgorithmSet
//------------------------------------------------------------

void
JKL_PopulateCachedAlgorithmSet();

void
JKL_PopulateCachedAlgorithmSet()
{
   CSPAttachMapIter i;
   AlgorithmSetIter j;

   // for every possible CSSM algorithm, associate it with an installed CSP
   // unsupported algorithms are not entered into cached algorithm map.

   for (i = gCSPAttachMap.begin(); i != gCSPAttachMap.end(); i++)
   {
      for (j = (*i).second.algorithmSet.begin(); j != (*i).second.algorithmSet.end(); j++)
      {
         uint32 algorithm = (*j);
         CachedAlgorithmMapIter k = gCachedAlgorithmMap.find(algorithm);
         if (k == gCachedAlgorithmMap.end())
         {
            gCachedAlgorithmMap[algorithm] = (*i).second.cspHandle;
         }
      }
   }
}


//------------------------------------------------------------
// function: JKL_FindBestCSP
//------------------------------------------------------------

uint32
JKL_FindBestCSP(CSSM_CSP_HANDLE& cspHandle, uint32 algorithm)
{
   cspHandle = 0;

   // search cached data

   CachedAlgorithmMapIter i = gCachedAlgorithmMap.find(algorithm);

   if (i != gCachedAlgorithmMap.end())
   {
      // found installed CSP which supports operation

      cspHandle = (*i).second;
      return 0;
   }

   // unable to find any installed CSP which supports operation

   return CSSM_CSP_OPERATION_UNSUPPORTED;
}


#if 0
uint32
JKL_FindBestCSP(CSSM_CSP_HANDLE& cspHandle, uint32 algorithm)
{
   cspHandle = 0;

   // search cached data

   CachedAlgorithmMapIter i = gCachedAlgorithmMap.find(algorithm);

   if (i != gCachedAlgorithmMap.end())
   {
      cspHandle = (*i).second;
      cout << "Using handle: " << cspHandle << " for algorithm " << algorithm << endl;
      return 0;

   }

   // algorithm not in cache, search attached modules for first that supports selected algorithm

   CSPAttachMapIter j;

   for (j = gCSPAttachMap.begin(); j != gCSPAttachMap.end(); j++)
   {
      cout << "Trying Handle: " << (*j).second.cspHandle << endl;
      if ((*j).second.algorithmSet.find(algorithm) != (*j).second.algorithmSet.end())
      {
         cspHandle = (*j).second.cspHandle;

         // update cache

         gCachedAlgorithmMap[algorithm] = cspHandle;

         cout << "Using handle: " << cspHandle << " for algorithm " << algorithm << endl;

         return 0;
      }
      else
      {
         cout << "Handle: " << (*j).second.cspHandle << " unsupport " << algorithm << endl;
      }
   }
   
   // unable to find any installed CSP which supports operation

   return CSSM_CSP_OPERATION_UNSUPPORTED;
}
#endif

//------------------------------------------------------------
// function: JKL_Initialize
//------------------------------------------------------------

uint32 
JKL_Initialize(CSSM_MEMORY_FUNCS& memoryFuncs)
{
   uint32 status = 0;

   //-------------------------------------------------
   // Initialize CSSM framework.
   // Save global copy of caller's CSSM memory 
   // functions; we will use them whenever we allocate 
   // CSSM_DATA or CSSM_KEY on user's behalf as part 
   // of asn_to_cssm routines
   //-------------------------------------------------

   gMemoryFuncs = memoryFuncs;

   CSSM_VERSION version = { CSSM_MAJOR, CSSM_MINOR };

   if (CSSM_FAIL == CSSM_Init(&version, &memoryFuncs, NULL))
      return CSSM_GetError()->error;
      
   // query framework for all installed CSP modules

   CSSM_LIST* moduleListPtr = CSSM_ListModules(CSSM_SERVICE_CSP, CSSM_FALSE);
   if (!moduleListPtr)
       return CSSM_GetError()->error;

   // iterate through installed CSPs; collect capability information and attach

   CSPAttachMapIter iter;

   for (int h = 0; h < moduleListPtr->NumberItems; h++)
   {
      CSSM_MODULE_INFO* moduleInfoPtr = CSSM_GetModuleInfo(&(moduleListPtr->Items[h].GUID),
                                                           CSSM_SERVICE_CSP,
                                                           CSSM_ALL_SUBSERVICES,
                                                           CSSM_INFO_LEVEL_ALL_ATTR);
      if (!moduleInfoPtr)
         return CSSM_GetError()->error;
   
      cout << "Description: " << moduleInfoPtr->Description << endl;

      // insert entry into CSP attach map for GUID

      GuidWrapper attr(moduleListPtr->Items[h].GUID);
      gCSPAttachMap[attr] = CSPAttachProperty();
      iter = gCSPAttachMap.find(attr);

      // process CSP capabilities

      for (int i = 0; i < moduleInfoPtr->NumberOfServices; i++)
      {
         CSSM_CSPSUBSERVICE* cspSubServicePtr = moduleInfoPtr->ServiceList[i].CspSubServiceList;
         for (int j = 0; j < moduleInfoPtr->ServiceList[i].NumberOfSubServices; j++)
         {
            CSSM_CSP_CAPABILITY* cspCapabilityPtr;

            switch (cspSubServicePtr->CspType)
            {
            case CSSM_CSP_SOFTWARE:
               {
                  CSSM_SOFTWARE_CSPSUBSERVICE_INFO* softwareSubServiceInfoPtr = &(cspSubServicePtr->SoftwareCspSubService);
                  for (int k = 0; k < softwareSubServiceInfoPtr->NumberOfCapabilities; k++)
                  {
                     cspCapabilityPtr = &(softwareSubServiceInfoPtr->CapabilityList[k]);
                     (*iter).second.algorithmSet.insert(cspCapabilityPtr->AlgorithmType);
                  }
                  break;
               }
            case CSSM_CSP_HARDWARE:
               {
                  CSSM_HARDWARE_CSPSUBSERVICE_INFO* hardwareSubServiceInfoPtr = &(cspSubServicePtr->HardwareCspSubService);
                  for (int k = 0; k < hardwareSubServiceInfoPtr->NumberOfCapabilities; k++)
                  {
                     cspCapabilityPtr = &(hardwareSubServiceInfoPtr->CapabilityList[k]);
                     (*iter).second.algorithmSet.insert(cspCapabilityPtr->AlgorithmType);
                  }
                  break;
               }
            default:
               {
                  break;
               }
            }  // switch
         }  // for each subservice
      }  // for each usage type
      
      CSSM_CSP_HANDLE cspHandle = CSSM_ModuleAttach(&(moduleListPtr->Items[h].GUID),
                                                    &moduleInfoPtr->Version,
                                                    &gMemoryFuncs,
                                                    0,
                                                    0,
                                                    0,
                                                    NULL,
                                                    NULL);
      if (!cspHandle)
         return CSSM_GetError()->error;
   
      if (CSSM_FreeModuleInfo(moduleInfoPtr) == CSSM_FAIL)
         return CSSM_GetError()->error;

      (*iter).second.cspHandle = cspHandle;
      cout << "Attached to " << cspHandle << endl;

   }   // for each installed CSP

   if (CSSM_FreeList(moduleListPtr) == CSSM_FAIL)
      return CSSM_GetError()->error;

   // populate algorithm lookup map

   JKL_PopulateCachedAlgorithmSet();

   return 0;
}

#if 0
//------------------------------------------------------------
// function: JKL_Initialize
//------------------------------------------------------------

uint32
JKL_Initialize(CSSM_MEMORY_FUNCS& memoryFuncs)
{
   CSSM_VERSION version = { CSSM_MAJOR, CSSM_MINOR };

   //-------------------------------------------------
   // Save global copy of caller's CSSM memory 
   // functions; we will use them whenever we allocate 
   // CSSM_DATA or CSSM_KEY on user's behalf as part 
   // of asn_to_cssm routines
   //-------------------------------------------------

   gMemoryFuncs = memoryFuncs;

   if (CSSM_FAIL == CSSM_Init(&version, &memoryFuncs, NULL))
      return CSSM_GetError()->error;

   return 0;
}
#endif

//------------------------------------------------------------
// function: JKL_AttachCSP
//------------------------------------------------------------

uint32
JKL_AttachCSP(const CSSM_GUID& selectedGUID, 
              CSSM_CSP_HANDLE& cspHandle)
{
   // there may be multiple CSP installed; load only specified GUID

   CSSM_MODULE_INFO* moduleInfoPtr = CSSM_GetModuleInfo((CSSM_GUID*)&selectedGUID,
                                                        CSSM_SERVICE_CSP,
                                                        CSSM_ALL_SUBSERVICES,
                                                        CSSM_INFO_LEVEL_ALL_ATTR);
   if (!moduleInfoPtr)
       return CSSM_GetError()->error;

   cspHandle = CSSM_ModuleAttach((CSSM_GUID*)&selectedGUID,
                                 &moduleInfoPtr->Version,
                                 &gMemoryFuncs,
                                 0,
                                 0,
                                 0,
                                 NULL,
                                 NULL);
   if (!cspHandle)
      return CSSM_GetError()->error;

   if (CSSM_FreeModuleInfo(moduleInfoPtr) == CSSM_FAIL)
       return CSSM_GetError()->error;

   return 0;
}


//------------------------------------------------------------
// function: JKL_AttachTP
//------------------------------------------------------------

uint32
JKL_AttachTP(const CSSM_GUID& cssmSelectedGUID, 
             CSSM_TP_HANDLE& tpHandle)
{
   CSSM_MODULE_INFO* moduleInfoPtr = CSSM_GetModuleInfo((CSSM_GUID*)&cssmSelectedGUID,
                                                        CSSM_SERVICE_TP,
                                                        CSSM_ALL_SUBSERVICES,
                                                        CSSM_INFO_LEVEL_ALL_ATTR);
   if (!moduleInfoPtr)
      return CSSM_GetError()->error;

   tpHandle = CSSM_ModuleAttach((CSSM_GUID*)&cssmSelectedGUID,
                                &moduleInfoPtr->Version,
                                &gMemoryFuncs,
                                0,
                                0,
                                0,
                                NULL,
                                NULL);
   if (!tpHandle)
      return CSSM_GetError()->error;

   if (CSSM_FreeModuleInfo(moduleInfoPtr) == CSSM_FAIL)
      return CSSM_GetError()->error;

   return 0;
}


//------------------------------------------------------------
// function: JKL_ModuleDetach
//------------------------------------------------------------

uint32
JKL_ModuleDetach(CSSM_MODULE_HANDLE cssmModuleHandle)

{
   CSSM_RETURN detached;

   detached = CSSM_ModuleDetach(cssmModuleHandle);
   if (detached != CSSM_OK)
      return CSSM_GetError()->error;

   return 0;
}


//*****************************************************************************
//
// GUID Utility Methods
//
//*****************************************************************************


//------------------------------------------------------------
// function: JKL_Get_SwCsp_GUID
//------------------------------------------------------------

const CSSM_GUID_PTR
JKL_Get_SwCsp_GUID()
{
   return &IBM_BSAFE_CSP_GUID;
}


//------------------------------------------------------------
// function: JKL_Get_CylinkCsp_GUID
//------------------------------------------------------------

const CSSM_GUID_PTR
JKL_Get_CylinkCsp_GUID()
{
   return &IBM_CYLINK_CSP_GUID;
}


//------------------------------------------------------------
// function: JKL_Get_JonahTp_GUID
//------------------------------------------------------------

const CSSM_GUID_PTR
JKL_Get_JonahTp_GUID()
{
   return &JONAH_TP_GUID;
}


//*****************************************************************************
//
// memory management.
//
//*****************************************************************************


//------------------------------------------------------------
// function: DefaultMalloc
//------------------------------------------------------------

void*
DefaultMalloc(uint32 size)
{
   return gMemoryFuncs.malloc_func(size, gMemoryFuncs.AllocRef);
}


//------------------------------------------------------------
// function: DefaultFree
//------------------------------------------------------------

void
DefaultFree(void* memPtr)
{
   gMemoryFuncs.free_func(memPtr, gMemoryFuncs.AllocRef);
}


//------------------------------------------------------------
// function: DefaultRealloc
//------------------------------------------------------------

void*
DefaultRealloc(void* memPtr,
               uint32 size)
{
   return gMemoryFuncs.realloc_func(memPtr, size, gMemoryFuncs.AllocRef);
}


//------------------------------------------------------------
// function: DefaultCalloc
//------------------------------------------------------------

void*
DefaultCalloc(uint32 num,
              uint32 size)
{
   return gMemoryFuncs.calloc_func(num, size, gMemoryFuncs.AllocRef);
}
