diff options
Diffstat (limited to 'security/nss/lib/fortcrypt/forsock.c')
-rw-r--r-- | security/nss/lib/fortcrypt/forsock.c | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/security/nss/lib/fortcrypt/forsock.c b/security/nss/lib/fortcrypt/forsock.c new file mode 100644 index 000000000..7479f8dd4 --- /dev/null +++ b/security/nss/lib/fortcrypt/forsock.c @@ -0,0 +1,819 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "fortsock.h" +#include "fpkmem.h" +#include "fmutex.h" +#include <string.h> +#include <stdlib.h> + +#define DEF_ENCRYPT_SIZE 0x8000 + +static unsigned char Fortezza_mail_Rb[128] = { +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1, +}; + +int InitSocket (FortezzaSocket *inSocket, int inSlotID) { + int ci_rv; + CK_RV mrv; + + if (inSocket == NULL) + return SOCKET_FAILURE; + + inSocket->isLoggedIn = PR_FALSE; + inSocket->personalitiesLoaded = PR_FALSE; + inSocket->isOpen = PR_FALSE; + inSocket->personalityList = NULL; + inSocket->keyRegisters = NULL; + inSocket->keys = NULL; + inSocket->numPersonalities = 0; + inSocket->numKeyRegisters = 0; + inSocket->hitCount = 0; + + inSocket->slotID = inSlotID; + ci_rv = MACI_GetSessionID(&(inSocket->maciSession)); + if (ci_rv != CI_OK) + return SOCKET_FAILURE; + + ci_rv = MACI_Open (inSocket->maciSession, 0, inSlotID); + if (ci_rv == CI_OK) { + inSocket->isOpen = PR_TRUE; + } else { + MACI_Close (inSocket->maciSession, CI_NULL_FLAG, inSlotID); + } + + if (FMUTEX_MutexEnabled()) { + mrv = FMUTEX_Create(&inSocket->registersLock); + if (mrv != CKR_OK) { + inSocket->registersLock = NULL; + } + } else { + inSocket->registersLock = NULL; + } + + return SOCKET_SUCCESS; +} + +int FreeSocket (FortezzaSocket *inSocket) { + if (inSocket->registersLock) { + FMUTEX_Destroy(inSocket->registersLock); + } + MACI_Close(inSocket->maciSession, CI_NULL_FLAG, inSocket->slotID); + return SOCKET_SUCCESS; +} + +int LoginToSocket (FortezzaSocket *inSocket, int inUserType, CI_PIN inPin) { + int ci_rv, i; + CI_STATUS ciStatus; + CI_CONFIG ciConfig; + FortezzaKey **oldRegisters, **newRegisters; + int oldCount; + HSESSION hs; + + if (inSocket == NULL || inSocket->isLoggedIn) + return SOCKET_FAILURE; + + hs = inSocket->maciSession; + ci_rv = MACI_Select (hs, inSocket->slotID); + if (ci_rv != CI_OK) + return ci_rv; + + ci_rv = MACI_CheckPIN(hs, inUserType, inPin); + + if (ci_rv != CI_OK) { + return ci_rv; + } + + ci_rv = MACI_GetStatus(hs, &ciStatus); + + if (ci_rv != CI_OK) { + if (ci_rv == CI_FAIL) { + ci_rv = CI_EXEC_FAIL; + } + return ci_rv; + } + + ci_rv = MACI_GetConfiguration(hs, &ciConfig); + if (ci_rv != CI_OK) { + return ci_rv; + } + + inSocket->isLoggedIn = PR_TRUE; + inSocket->hasLoggedIn = PR_TRUE; + PORT_Memcpy (inSocket->openCardSerial, ciStatus.SerialNumber, + sizeof (CI_SERIAL_NUMBER)); + inSocket->openCardState = ciStatus.CurrentState; + inSocket->numPersonalities = ciStatus.CertificateCount; + inSocket->numKeyRegisters = ciConfig.KeyRegisterCount; + newRegisters = + (FortezzaKey**)PORT_Alloc (sizeof(FortezzaKey)*ciConfig.KeyRegisterCount); + + FMUTEX_Lock(inSocket->registersLock); + oldRegisters = inSocket->keyRegisters; + oldCount = inSocket->numKeyRegisters; + inSocket->keyRegisters = newRegisters; + if (oldRegisters) { + for (i=0; i<oldCount; i++) { + if (oldRegisters[i]) { + oldRegisters[i]->keyRegister = KeyNotLoaded; + } + oldRegisters[i] = NULL; + } + PORT_Free(oldRegisters); + } + + if (inSocket->keyRegisters == NULL) { + FMUTEX_Unlock(inSocket->registersLock); + return SOCKET_FAILURE; + } + + for (i=0; i<ciConfig.KeyRegisterCount; i++) { + inSocket->keyRegisters[i] = NULL; + } + FMUTEX_Unlock(inSocket->registersLock); + + return SOCKET_SUCCESS; +} + +int LogoutFromSocket (FortezzaSocket *inSocket) { + if (inSocket == NULL) + return SOCKET_FAILURE; + + inSocket->isLoggedIn = PR_FALSE; + inSocket->hasLoggedIn = PR_FALSE; + if (UnloadPersonalityList(inSocket) != SOCKET_SUCCESS) + return SOCKET_FAILURE; + + + return SOCKET_SUCCESS; +} + + +int FetchPersonalityList(FortezzaSocket *inSocket) { + int rv; + + if (inSocket == NULL || inSocket->numPersonalities == 0) { + return SOCKET_FAILURE; + } + + rv = MACI_Select (inSocket->maciSession, inSocket->slotID); + + inSocket->personalityList = + (CI_PERSON*)PORT_Alloc (sizeof(CI_PERSON)*inSocket->numPersonalities); + + if (inSocket->personalityList == NULL) { + return SOCKET_FAILURE; + } + + rv = MACI_GetPersonalityList(inSocket->maciSession, + inSocket->numPersonalities, + inSocket->personalityList); + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + inSocket->personalitiesLoaded = PR_TRUE; + return SOCKET_SUCCESS; +} + +int UnloadPersonalityList(FortezzaSocket *inSocket) { + if (inSocket == NULL) + return SOCKET_FAILURE; + + inSocket->personalitiesLoaded = PR_FALSE; + if (inSocket->personalityList) { + PORT_Free(inSocket->personalityList); + } + inSocket->numPersonalities = 0; + inSocket->personalityList = NULL; + + return SOCKET_SUCCESS; +} + +PRBool SocketIsLoggedIn(CI_STATE status) { + + return (PRBool)((status == CI_READY) || (status == CI_STANDBY)); +} + +PRBool SocketStateUnchanged(FortezzaSocket* inSocket) { + CI_STATUS ciStatus; + int ciRV; + + ciRV = MACI_Select (inSocket->maciSession, inSocket->slotID); + if (ciRV != CI_OK) + return PR_FALSE; + + if (inSocket->hasLoggedIn && !inSocket->isLoggedIn) + return PR_FALSE; /* User Logged out from the socket */ + + /* + * Some vendor cards are slow. so if we think we are logged in, + * and the card still thinks we're logged in, we must have the same + * card. + */ + if (inSocket->isLoggedIn) { + CI_STATE state; + ciRV = MACI_GetState(inSocket->maciSession, &state); + if (ciRV != CI_OK) return PR_FALSE; + + return SocketIsLoggedIn(state); + } + + ciRV = MACI_GetStatus(inSocket->maciSession, &ciStatus); + if(ciRV != CI_OK) { + return PR_FALSE; + } + if (inSocket->isLoggedIn) { + if (PORT_Memcmp(ciStatus.SerialNumber, inSocket->openCardSerial, + sizeof (CI_SERIAL_NUMBER)) != 0) + return PR_FALSE; /* Serial Number of card in slot has changed */ + /* Probably means there is a new card */ + } + + if (inSocket->isLoggedIn && !SocketIsLoggedIn(ciStatus.CurrentState)) + return PR_FALSE; /* State of card changed. */ + /* Probably re-inserted same card */ + + return PR_TRUE; /* No change in the state of the socket */ +} + +/* + * can we regenerate this key on the fly? + */ +static PRBool +FortezzaIsRegenerating(FortezzaKey *key) { + /* TEK's are the only type of key that can't be regenerated */ + if (key->keyType != TEK) return PR_TRUE; + /* Client TEK's can never be regenerated */ + if (key->keyData.tek.flags == CI_INITIATOR_FLAG) return PR_FALSE; + /* Only Server TEK's that use the Mail protocol can be regenerated */ + return ((PRBool)(memcmp(key->keyData.tek.Rb,Fortezza_mail_Rb, + sizeof(key->keyData.tek.Rb)) == 0)); +} + +int GetBestKeyRegister(FortezzaSocket *inSocket) { + int i, candidate = -1, candidate2 = 1; + CK_ULONG minHitCount = 0xffffffff; + CK_ULONG minRegHitCount = 0xffffffff; + FortezzaKey **registers; + + registers = inSocket->keyRegisters; + for (i=1; i< inSocket->numKeyRegisters; i++) { + if (registers[i] == NULL) + return i; + } + + for (i=1; i < inSocket->numKeyRegisters; i++) { + if (registers[i]->hitCount < minHitCount) { + minHitCount = registers[i]->hitCount; + candidate2 = i; + } + + if (FortezzaIsRegenerating(registers[i]) && + (registers[i]->hitCount < minRegHitCount)) { + minRegHitCount = registers[i]->hitCount; + candidate = i; + } + } + + if (candidate == -1) + candidate = candidate2; + + return candidate; +} + +int SetFortezzaKeyHandle (FortezzaKey *inKey, CK_OBJECT_HANDLE inHandle) { + inKey->keyHandle = inHandle; + return SOCKET_SUCCESS; +} + +void +RemoveKey (FortezzaKey *inKey) { + if (inKey != NULL && inKey->keySocket->keyRegisters != NULL) { + if (inKey->keyRegister != KeyNotLoaded) { + FortezzaKey **registers = inKey->keySocket->keyRegisters; + registers[inKey->keyRegister] = NULL; + MACI_DeleteKey(inKey->keySocket->maciSession, inKey->keyRegister); + } + + PORT_Free(inKey); + } +} + +FortezzaKey *NewFortezzaKey(FortezzaSocket *inSocket, + FortezzaKeyType inKeyType, + CreateTEKInfo *TEKinfo, + int inKeyRegister) { + FortezzaKey *newKey, *oldKey; + FortezzaKey **registers; + HSESSION hs = inSocket->maciSession; + int ciRV; + + newKey = (FortezzaKey*)PORT_Alloc (sizeof(FortezzaKey)); + if (newKey == NULL) { + return NULL; + } + + newKey->keyHandle = 0; + newKey->keyRegister = KeyNotLoaded; + newKey->keyType = inKeyType; + newKey->keySocket = inSocket; + newKey->hitCount = 0; + newKey->id = TEKinfo ? TEKinfo->personality : 0; + + if (inKeyType != Ks && inSocket->keyRegisters) { + registers = inSocket->keyRegisters; + oldKey = registers[inKeyRegister]; + if (oldKey != NULL) { + oldKey->keyRegister = KeyNotLoaded; + } + + registers[inKeyRegister] = newKey; + newKey->hitCount = inSocket->hitCount++; + + MACI_DeleteKey (hs, inKeyRegister); + } + newKey->keyRegister = inKeyRegister; + + MACI_Lock(hs, CI_BLOCK_LOCK_FLAG); + switch (inKeyType) { + case MEK: + ciRV = MACI_GenerateMEK (hs, inKeyRegister, 0); + if (ciRV != CI_OK) { + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + MACI_WrapKey(hs, 0, inKeyRegister, newKey->keyData.mek); + break; + case TEK: + PORT_Memcpy (newKey->keyData.tek.Rb, TEKinfo->Rb, TEKinfo->randomLen); + PORT_Memcpy (newKey->keyData.tek.Ra, TEKinfo->Ra, TEKinfo->randomLen); + PORT_Memcpy (newKey->keyData.tek.pY, TEKinfo->pY, TEKinfo->YSize); + newKey->keyData.tek.ySize = TEKinfo->YSize; + newKey->keyData.tek.randomLen = TEKinfo->randomLen; + newKey->keyData.tek.registerIndex = TEKinfo->personality; + newKey->keyData.tek.flags = TEKinfo->flag; + + ciRV = MACI_SetPersonality(hs,TEKinfo->personality); + if (ciRV != CI_OK) { + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + ciRV = MACI_GenerateTEK(hs, TEKinfo->flag, inKeyRegister, + newKey->keyData.tek.Ra, TEKinfo->Rb, + TEKinfo->YSize, TEKinfo->pY); + if (ciRV != CI_OK) { + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + + + break; + case Ks: + break; + default: + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + MACI_Unlock(hs); + return newKey; +} + +FortezzaKey *NewUnwrappedKey(int inKeyRegister, int id, + FortezzaSocket *inSocket) { + FortezzaKey *newKey; + + newKey = (FortezzaKey*)PORT_Alloc (sizeof(FortezzaKey)); + if (newKey == NULL) { + return NULL; + } + + newKey->keyRegister = inKeyRegister; + newKey->keyType = UNWRAP; + newKey->keySocket = inSocket; + newKey->id = id; + newKey->hitCount = inSocket->hitCount++; + MACI_WrapKey(inSocket->maciSession,0 , inKeyRegister, newKey->keyData.mek); + inSocket->keyRegisters[inKeyRegister] = newKey; + + return newKey; +} + +int LoadKeyIntoRegister (FortezzaKey *inKey) { + int registerIndex = GetBestKeyRegister(inKey->keySocket); + FortezzaSocket *socket = inKey->keySocket; + FortezzaKey **registers = socket->keyRegisters; + HSESSION hs = socket->maciSession; + FortezzaTEK *tek = &inKey->keyData.tek; + FortezzaKey *oldKey; + int rv = CI_FAIL; + + if (inKey->keyRegister != KeyNotLoaded) { + return inKey->keyRegister; + } + + oldKey = registers[registerIndex]; + + MACI_Select(hs, socket->slotID); + if (oldKey) { + oldKey->keyRegister = KeyNotLoaded; + } + MACI_DeleteKey (hs, registerIndex); + + switch (inKey->keyType) { + case TEK: + if (!FortezzaIsRegenerating(inKey)) { + return KeyNotLoaded; + } + if (MACI_SetPersonality(hs, tek->registerIndex) == CI_OK) { + rv = MACI_GenerateTEK (hs, tek->flags, registerIndex, + tek->Ra, tek->Rb, tek->ySize, + tek->pY); + } + if (rv != CI_OK) + return KeyNotLoaded; + break; + case MEK: + case UNWRAP: + rv = MACI_UnwrapKey (hs, 0, registerIndex, inKey->keyData.mek); + if (rv != CI_OK) + return KeyNotLoaded; + break; + default: + return KeyNotLoaded; + } + inKey->keyRegister = registerIndex; + registers[registerIndex] = inKey; + + return registerIndex; +} + +int InitCryptoOperation (FortezzaContext *inContext, + CryptoType inCryptoOperation) { + inContext->cryptoOperation = inCryptoOperation; + return SOCKET_SUCCESS; +} + +int EndCryptoOperation (FortezzaContext *inContext, + CryptoType inCryptoOperation) { + if (inCryptoOperation != inContext->cryptoOperation) { + return SOCKET_FAILURE; + } + inContext->cryptoOperation = None; + return SOCKET_SUCCESS; +} + +CryptoType GetCryptoOperation (FortezzaContext *inContext) { + return inContext->cryptoOperation; +} + +void InitContext(FortezzaContext *inContext, FortezzaSocket *inSocket, + CK_OBJECT_HANDLE hKey) { + inContext->fortezzaKey = NULL; + inContext->fortezzaSocket = inSocket; + inContext->session = NULL; + inContext->mechanism = NO_MECHANISM; + inContext->userRamSize = 0; + inContext->cryptoOperation = None; + inContext->hKey = hKey; +} + +extern PRBool fort11_FortezzaIsUserCert(unsigned char *label); + +static int +GetValidPersonality (FortezzaSocket *inSocket) { + int index = -1; /* return an invalid personalidyt if one isn't found */ + int i; + PRBool unLoadList = PR_FALSE; + int numPersonalities = 0; + + if (!inSocket->personalitiesLoaded) { + numPersonalities = inSocket->numPersonalities; + FetchPersonalityList (inSocket); + unLoadList = PR_TRUE; + } + + for (i=0; i<inSocket->numPersonalities; i++) { + if (fort11_FortezzaIsUserCert(inSocket->personalityList[i].CertLabel)) { + index = inSocket->personalityList[i].CertificateIndex; + break; + } + } + + if (unLoadList) { + UnloadPersonalityList(inSocket); + /* UnloadPersonality sets numPersonalities to zero, + * so we set it back to what it was when this function + * was called. + */ + inSocket->numPersonalities = numPersonalities; + } + return index; +} + +int RestoreState (FortezzaContext *inContext, CryptoType inType) { + FortezzaKey *key = inContext->fortezzaKey; + FortezzaSocket *socket = inContext->fortezzaSocket; + HSESSION hs = socket->maciSession; + CI_IV bogus_iv; + int rv, cryptoType = -1; + int personality = inContext->fortezzaKey->id; + + if (key == NULL) + return SOCKET_FAILURE; + + if (personality == 0) { + personality = GetValidPersonality (socket); + } + rv = MACI_SetPersonality(hs, personality); + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + /* + * The cards need to have some state bits set because + * save and restore don't necessarily save all the state. + * Instead of fixing the cards, they decided to change the + * protocol :(. + */ + switch (inType) { + case Encrypt: + rv = MACI_SetKey(hs, key->keyRegister); + if (rv != CI_OK) + break; + rv = MACI_GenerateIV (hs, bogus_iv); + cryptoType = CI_ENCRYPT_EXT_TYPE; + break; + case Decrypt: + rv = MACI_SetKey(hs, key->keyRegister); + rv = MACI_LoadIV (hs, inContext->cardIV); + cryptoType = CI_DECRYPT_EXT_TYPE; + break; + default: + rv = CI_INV_POINTER; + break; + } + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + /*PORT_Assert(cryptoType != -1); */ + + rv = MACI_Restore(hs, cryptoType, inContext->cardState); + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + return SOCKET_SUCCESS; +} + +int SaveState (FortezzaContext *inContext, CI_IV inIV, + PK11Session *inSession, FortezzaKey *inKey, + int inCryptoType, CK_MECHANISM_TYPE inMechanism){ + int ciRV; + FortezzaSocket *socket = inContext->fortezzaSocket; + HSESSION hs = socket->maciSession; + CI_CONFIG ciConfig; + + ciRV = MACI_Select (hs, socket->slotID); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + inContext->session = inSession; + inContext->fortezzaKey = inKey; + inContext->mechanism = inMechanism; + PORT_Memcpy (inContext->cardIV, inIV, sizeof (CI_IV)); + ciRV = MACI_Save(hs, inCryptoType, inContext->cardState); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + ciRV = MACI_GetConfiguration (hs, &ciConfig); + if (ciRV == CI_OK) { + inContext->userRamSize = ciConfig.LargestBlockSize; + } + + if (inContext->userRamSize == 0) inContext->userRamSize = 0x4000; + + return SOCKET_SUCCESS; +} + +int SocketSaveState (FortezzaContext *inContext, int inCryptoType) { + int ciRV; + + ciRV = MACI_Save (inContext->fortezzaSocket->maciSession, inCryptoType, + inContext->cardState); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + return SOCKET_SUCCESS; +} + +int DecryptData (FortezzaContext *inContext, + CK_BYTE_PTR inData, + CK_ULONG inDataLen, + CK_BYTE_PTR inDest, + CK_ULONG inDestLen) { + FortezzaSocket *socket = inContext->fortezzaSocket; + FortezzaKey *key = inContext->fortezzaKey; + HSESSION hs = socket->maciSession; + CK_ULONG defaultEncryptSize; + CK_ULONG left = inDataLen; + CK_BYTE_PTR loopin, loopout; + int rv = CI_OK; + + MACI_Select (hs, socket->slotID); + + defaultEncryptSize = (inContext->userRamSize > DEF_ENCRYPT_SIZE) + ? DEF_ENCRYPT_SIZE : inContext->userRamSize; + + if (key->keyRegister == KeyNotLoaded) { + rv = LoadKeyIntoRegister(key); + if (rv == KeyNotLoaded) { + return SOCKET_FAILURE; + } + } + + key->hitCount = socket->hitCount++; + loopin = inData; + loopout = inDest; + left = inDataLen; + rv = CI_OK; + + MACI_Lock(hs, CI_BLOCK_LOCK_FLAG); + RestoreState (inContext, Decrypt); + + while ((left > 0) && (rv == CI_OK)) { + CK_ULONG current = (left > defaultEncryptSize) + ? defaultEncryptSize : left; + rv = MACI_Decrypt(hs, current, loopin, loopout); + loopin += current; + loopout += current; + left -= current; + } + + MACI_Unlock(hs); + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + + rv = SocketSaveState (inContext, CI_DECRYPT_EXT_TYPE); + if (rv != SOCKET_SUCCESS) { + return rv; + } + + + return SOCKET_SUCCESS; +} + +int EncryptData (FortezzaContext *inContext, + CK_BYTE_PTR inData, + CK_ULONG inDataLen, + CK_BYTE_PTR inDest, + CK_ULONG inDestLen) { + FortezzaSocket *socket = inContext->fortezzaSocket; + FortezzaKey *key = inContext->fortezzaKey; + HSESSION hs = socket->maciSession; + CK_ULONG defaultEncryptSize; + CK_ULONG left = inDataLen; + CK_BYTE_PTR loopin, loopout; + int rv = CI_OK; + + MACI_Select (hs, socket->slotID); + + defaultEncryptSize = (inContext->userRamSize > DEF_ENCRYPT_SIZE) + ? DEF_ENCRYPT_SIZE : inContext->userRamSize; + if (key->keyRegister == KeyNotLoaded) { + rv = LoadKeyIntoRegister(key); + if (rv == KeyNotLoaded) { + return rv; + } + } + + key->hitCount = socket->hitCount++; + loopin = inData; + loopout = inDest; + + RestoreState (inContext,Encrypt); + + rv = CI_OK; + while ((left > 0) && (rv == CI_OK)) { + CK_ULONG current = (left > defaultEncryptSize) ? defaultEncryptSize : + left; + rv = MACI_Encrypt(hs, current, loopin, loopout); + loopin += current; + loopout += current; + left -= current; + } + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + rv = SocketSaveState (inContext, CI_ENCRYPT_EXT_TYPE); + if (rv != SOCKET_SUCCESS) { + return rv; + } + + return SOCKET_SUCCESS; +} + +int WrapKey (FortezzaKey *wrappingKey, FortezzaKey *srcKey, + CK_BYTE_PTR pDest, CK_ULONG ulDestLen) { + int ciRV; + HSESSION hs = wrappingKey->keySocket->maciSession; + + if (wrappingKey->keyRegister == KeyNotLoaded) { + if (LoadKeyIntoRegister(wrappingKey) == KeyNotLoaded) { + return SOCKET_FAILURE; + } + } + + if (srcKey->id == 0) srcKey->id = wrappingKey->id; + + ciRV = MACI_WrapKey (hs, wrappingKey->keyRegister, + srcKey->keyRegister, pDest); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + + return SOCKET_SUCCESS; +} + +int UnwrapKey (CK_BYTE_PTR inWrappedKey, FortezzaKey *inUnwrapKey) { + int newIndex; + int ciRV; + FortezzaSocket *socket = inUnwrapKey->keySocket; + HSESSION hs = socket->maciSession; + FortezzaKey *oldKey; + + if (inUnwrapKey->keyRegister == KeyNotLoaded) { + if (LoadKeyIntoRegister(inUnwrapKey) == KeyNotLoaded) { + return KeyNotLoaded; + } + } + + ciRV = MACI_Select(hs, socket->slotID); + if (ciRV != CI_OK) { + return KeyNotLoaded; + } + + newIndex = GetBestKeyRegister(inUnwrapKey->keySocket); + oldKey = socket->keyRegisters[newIndex]; + + MACI_Select(hs, socket->slotID); + if (oldKey) { + oldKey->keyRegister = KeyNotLoaded; + socket->keyRegisters[newIndex] = NULL; + } + MACI_DeleteKey (hs, newIndex); + ciRV = MACI_UnwrapKey(hs,inUnwrapKey->keyRegister, newIndex, inWrappedKey); + if (ciRV != CI_OK) { + inUnwrapKey->keyRegister = KeyNotLoaded; + socket->keyRegisters[newIndex] = NULL; + return KeyNotLoaded; + } + + return newIndex; +} + |