Paul Gofman : rsaenh: Factor out block_encrypt() function.

Alexandre Julliard julliard at winehq.org
Mon May 16 15:37:59 CDT 2022


Module: wine
Branch: master
Commit: dc9ab100fde217579185391c620445952babce54
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=dc9ab100fde217579185391c620445952babce54

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Fri May 13 14:21:44 2022 -0500

rsaenh: Factor out block_encrypt() function.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/rsaenh/rsaenh.c | 124 +++++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 54 deletions(-)

diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c
index 140fdec40d5..76122be2756 100644
--- a/dlls/rsaenh/rsaenh.c
+++ b/dlls/rsaenh/rsaenh.c
@@ -96,7 +96,7 @@ typedef struct tagCRYPTKEY
     DWORD       dwSaltLen;
     DWORD       dwBlockLen;
     DWORD       dwState;
-    KEY_CONTEXT context;    
+    KEY_CONTEXT context;
     BYTE        abKeyValue[RSAENH_MAX_KEY_SIZE];
     BYTE        abInitVector[RSAENH_MAX_BLOCK_SIZE];
     BYTE        abChainVector[RSAENH_MAX_BLOCK_SIZE];
@@ -526,6 +526,73 @@ static inline void init_data_blob(PCRYPT_DATA_BLOB pBlob) {
     pBlob->cbData = 0;
 }
 
+/******************************************************************************
+ * block_encrypt [Internal]
+ */
+BOOL block_encrypt(CRYPTKEY *key, BYTE *data, DWORD *data_len, DWORD buf_len,
+                   BOOL final, KEY_CONTEXT *context, BYTE *chain_vector)
+{
+    BYTE *in, out[RSAENH_MAX_BLOCK_SIZE], o[RSAENH_MAX_BLOCK_SIZE];
+    unsigned int encrypted_len, i, j, k;
+
+    if (!final && (*data_len % key->dwBlockLen))
+    {
+        SetLastError(NTE_BAD_DATA);
+        return FALSE;
+    }
+
+    encrypted_len = (*data_len / key->dwBlockLen + (final ? 1 : 0)) * key->dwBlockLen;
+
+    if (data == NULL)
+    {
+        *data_len = encrypted_len;
+        return TRUE;
+    }
+    if (encrypted_len > buf_len)
+    {
+        *data_len = encrypted_len;
+        SetLastError(ERROR_MORE_DATA);
+        return FALSE;
+    }
+
+    /* Pad final block with length bytes */
+    for (i = *data_len; i < encrypted_len; i++) data[i] = encrypted_len - *data_len;
+    *data_len = encrypted_len;
+
+    for (i = 0, in = data; i < *data_len; i += key->dwBlockLen, in += key->dwBlockLen)
+    {
+        switch (key->dwMode) {
+            case CRYPT_MODE_ECB:
+                encrypt_block_impl(key->aiAlgid, 0, context, in, out,
+                                   RSAENH_ENCRYPT);
+                break;
+            case CRYPT_MODE_CBC:
+                for (j = 0; j < key->dwBlockLen; j++)
+                    in[j] ^= chain_vector[j];
+                encrypt_block_impl(key->aiAlgid, 0, context, in, out,
+                                   RSAENH_ENCRYPT);
+                memcpy(chain_vector, out, key->dwBlockLen);
+                break;
+            case CRYPT_MODE_CFB:
+                for (j = 0; j < key->dwBlockLen; j++)
+                {
+                    encrypt_block_impl(key->aiAlgid, 0, context,
+                                       chain_vector, o, RSAENH_ENCRYPT);
+                    out[j] = in[j] ^ o[0];
+                    for (k = 0; k < key->dwBlockLen - 1; k++)
+                        chain_vector[k] = chain_vector[k+1];
+                    chain_vector[k] = out[j];
+                }
+                break;
+            default:
+                SetLastError(NTE_BAD_ALGID);
+                return FALSE;
+        }
+        memcpy(in, out, key->dwBlockLen);
+    }
+    return TRUE;
+}
+
 /******************************************************************************
  * free_hmac_info [Internal]
  *
@@ -2515,8 +2582,6 @@ BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
                              DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
 {
     CRYPTKEY *pCryptKey;
-    BYTE *in, out[RSAENH_MAX_BLOCK_SIZE], o[RSAENH_MAX_BLOCK_SIZE];
-    DWORD dwEncryptedLen, i, j, k;
         
     TRACE("(hProv=%08Ix, hKey=%08Ix, hHash=%08Ix, Final=%d, dwFlags=%08lx, pbData=%p, "
           "pdwDataLen=%p, dwBufLen=%ld)\n", hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen,
@@ -2554,58 +2619,9 @@ BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
     }
     
     if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_BLOCK) {
-        if (!Final && (*pdwDataLen % pCryptKey->dwBlockLen)) {
-            SetLastError(NTE_BAD_DATA);
+        if (!block_encrypt(pCryptKey, pbData, pdwDataLen, dwBufLen, Final,
+                           &pCryptKey->context, pCryptKey->abChainVector))
             return FALSE;
-        }
-
-        dwEncryptedLen = (*pdwDataLen/pCryptKey->dwBlockLen+(Final?1:0))*pCryptKey->dwBlockLen;
-
-        if (pbData == NULL) {
-            *pdwDataLen = dwEncryptedLen;
-            return TRUE;
-        }
-        else if (dwEncryptedLen > dwBufLen) {
-            *pdwDataLen = dwEncryptedLen;
-            SetLastError(ERROR_MORE_DATA);
-            return FALSE;
-        }
-
-        /* Pad final block with length bytes */
-        for (i=*pdwDataLen; i<dwEncryptedLen; i++) pbData[i] = dwEncryptedLen - *pdwDataLen;
-        *pdwDataLen = dwEncryptedLen;
-
-        for (i=0, in=pbData; i<*pdwDataLen; i+=pCryptKey->dwBlockLen, in+=pCryptKey->dwBlockLen) {
-            switch (pCryptKey->dwMode) {
-                case CRYPT_MODE_ECB:
-                    encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out, 
-                                       RSAENH_ENCRYPT);
-                    break;
-                
-                case CRYPT_MODE_CBC:
-                    for (j=0; j<pCryptKey->dwBlockLen; j++) in[j] ^= pCryptKey->abChainVector[j];
-                    encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out, 
-                                       RSAENH_ENCRYPT);
-                    memcpy(pCryptKey->abChainVector, out, pCryptKey->dwBlockLen);
-                    break;
-
-                case CRYPT_MODE_CFB:
-                    for (j=0; j<pCryptKey->dwBlockLen; j++) {
-                        encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, 
-                                           pCryptKey->abChainVector, o, RSAENH_ENCRYPT);
-                        out[j] = in[j] ^ o[0];
-                        for (k=0; k<pCryptKey->dwBlockLen-1; k++) 
-                            pCryptKey->abChainVector[k] = pCryptKey->abChainVector[k+1];
-                        pCryptKey->abChainVector[k] = out[j];
-                    }
-                    break;
-                    
-                default:
-                    SetLastError(NTE_BAD_ALGID);
-                    return FALSE;
-            }
-            memcpy(in, out, pCryptKey->dwBlockLen); 
-        }
     } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
         if (pbData == NULL) {
             *pdwDataLen = dwBufLen;




More information about the wine-cvs mailing list