VirtualBox

Changeset 95027 in vbox for trunk/src/VBox/Main/testcase


Ignore:
Timestamp:
May 16, 2022 6:54:09 PM (3 years ago)
Author:
vboxsync
Message:

Main/testcases/tstVBoxCrypto.cpp: Some basic testcase for the VFS file part, bugref:9955

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/testcase/tstVBoxCrypto.cpp

    r94980 r95027  
    2323#include <VBox/err.h>
    2424
     25#include <iprt/file.h>
    2526#include <iprt/test.h>
    2627#include <iprt/ldr.h>
    2728#include <iprt/mem.h>
    2829#include <iprt/memsafer.h>
     30#include <iprt/rand.h>
    2931#include <iprt/string.h>
    3032#include <iprt/vfs.h>
     
    5254#define CHECK_STR(str1, str2)  do { if (strcmp(str1, str2)) { RTTestIFailed("line %u: '%s' != '%s' (*)", __LINE__, str1, str2); } } while (0)
    5355#define CHECK_BYTES(bytes1, bytes2, size)  do { if (memcmp(bytes1, bytes2, size)) { RTTestIFailed("line %u: '%s' != '%s' (*)", __LINE__, #bytes1, bytes2); } } while (0)
     56
     57
     58/**
     59 * Creates a new cryptographic context and returns the encoded string version on success.
     60 * 
     61 * @returns VBox status code.
     62 * @param   pCryptoIf           Pointer to the cryptographic interface.
     63 * @param   pszCipher           The cipher to use.
     64 * @param   pszPassword         The password to use.
     65 * @param   ppszCtx             Where to store the pointer to the context on success.
     66 */
     67static int tstCryptoCtxCreate(PCVBOXCRYPTOIF pCryptoIf, const char *pszCipher, const char *pszPassword, char **ppszCtx)
     68{
     69    VBOXCRYPTOCTX hCryptoCtx;
     70
     71    int rc = pCryptoIf->pfnCryptoCtxCreate(pszCipher, pszPassword, &hCryptoCtx);
     72    if ((RT_SUCCESS(rc)))
     73    {
     74        rc = pCryptoIf->pfnCryptoCtxSave(hCryptoCtx, ppszCtx);
     75        int rc2 = pCryptoIf->pfnCryptoCtxDestroy(hCryptoCtx);
     76        AssertReleaseRC(rc2);
     77    }
     78
     79    return rc;
     80}
     81
     82
     83/**
     84 * Writes data to the given file until the given size is reached.
     85 * 
     86 * @returns VBox status code.
     87 * @param   hVfsFile            The file handle to write to.
     88 * @param   cbWrite             Number of bytes to write.
     89 */
     90static int tstCryptoVfsWrite(RTVFSFILE hVfsFile, size_t cbWrite)
     91{
     92    RTTestISub("Writing to encrypted file");
     93
     94    int rc = VINF_SUCCESS;
     95    size_t cbBufLeft = _128K;
     96    void *pv = RTMemTmpAllocZ(cbBufLeft);
     97    if (pv)
     98    {
     99        size_t cbLeft = cbWrite;
     100        uint32_t cCounter = 0;
     101        uint8_t *pb = (uint8_t *)pv;
     102
     103        /* Fill the counter buffer. */
     104        uint32_t *pu32 = (uint32_t *)pv;
     105        for (uint32_t i = 0; i < cbBufLeft / sizeof(uint32_t); i++)
     106            *pu32++ = cCounter++;
     107
     108
     109        for (;;)
     110        {
     111            size_t cbThisWrite = RTRandU64Ex(1, RT_MIN(cbBufLeft, cbLeft));
     112            rc = RTVfsFileWrite(hVfsFile, pb, cbThisWrite, NULL /*pcbWritten*/);
     113            if (RT_FAILURE(rc))
     114            {
     115                RTTestIFailed("Writing to file failed with %Rrc (cbLeft=%zu, cbBufLeft=%zu, cbThisWrite=%zu)",
     116                              rc, cbLeft, cbBufLeft, cbThisWrite);
     117                break;
     118            }
     119
     120            cbLeft    -= cbThisWrite;
     121            cbBufLeft -= cbThisWrite;
     122            pb        += cbThisWrite;
     123
     124            if (!cbBufLeft)
     125            {
     126                /* Fill the counter buffer again. */
     127                pu32 = (uint32_t *)pv;
     128                pb = (uint8_t *)pv;
     129                cbBufLeft = _128K;
     130                for (uint32_t i = 0; i < cbBufLeft / sizeof(uint32_t); i++)
     131                    *pu32++ = cCounter++;
     132            }
     133
     134            if (!cbLeft)
     135                break;
     136        }
     137
     138        RTMemTmpFree(pv);
     139    }
     140    else
     141    {
     142        RTTestIFailed("Allocating write buffer failed - out of memory");
     143        rc = VERR_NO_MEMORY;
     144    }
     145
     146    RTTestISubDone();
     147    return rc;
     148}
     149
     150
     151/**
     152 * Writes data to the given file until the given size is reached.
     153 * 
     154 * @returns VBox status code.
     155 * @param   hVfsFile            The file handle to write to.
     156 * @param   cbFile              Size of the file payload in bytes.
     157 */
     158static int tstCryptoVfsReadAndVerify(RTVFSFILE hVfsFile, size_t cbFile)
     159{
     160    RTTestISub("Reading from encrypted file and verifying data");
     161
     162    int rc = VINF_SUCCESS;
     163    void *pv = RTMemTmpAllocZ(_128K);
     164    if (pv)
     165    {
     166        size_t cbLeft = cbFile;
     167        uint32_t cCounter = 0;
     168
     169        for (;;)
     170        {
     171            /* Read the data in multiple calls. */
     172            size_t cbBufLeft = RT_MIN(cbLeft, _128K);
     173            uint8_t *pb = (uint8_t *)pv;
     174
     175            while (cbBufLeft)
     176            {
     177                size_t cbThisRead = RTRandU64Ex(1, RT_MIN(cbBufLeft, cbLeft));
     178                rc = RTVfsFileRead(hVfsFile, pb, cbThisRead, NULL /*pcbWritten*/);
     179                if (RT_FAILURE(rc))
     180                {
     181                    RTTestIFailed("Reading from file failed with %Rrc (cbLeft=%zu, cbBufLeft=%zu, cbThisRead=%zu)",
     182                                  rc, cbLeft, cbBufLeft, cbThisRead);
     183                    break;
     184                }
     185
     186                cbBufLeft -= cbThisRead;
     187                pb        += cbThisRead;
     188            }
     189
     190            if (RT_FAILURE(rc))
     191                break;
     192
     193            /* Verify the read data. */
     194            size_t cbInBuffer = RT_MIN(cbLeft, _128K);
     195            Assert(!(cbInBuffer % sizeof(uint32_t)));
     196            uint32_t *pu32 = (uint32_t *)pv;
     197
     198            for (uint32_t i = 0; i < cbInBuffer / sizeof(uint32_t); i++)
     199            {
     200                if (*pu32 != cCounter)
     201                {
     202                    RTTestIFailed("Reading from file resulted in corrupted data (expected '%#x' got '%#x')",
     203                                  cCounter, *pu32);
     204                    break;
     205                }
     206
     207                pu32++;
     208                cCounter++;
     209            }
     210
     211            cbLeft -= RT_MIN(cbLeft, _128K);
     212            if (!cbLeft)
     213                break;
     214        }
     215
     216        RTMemTmpFree(pv);
     217    }
     218    else
     219    {
     220        RTTestIFailed("Allocating read buffer failed - out of memory");
     221        rc = VERR_NO_MEMORY;
     222    }
     223
     224    RTTestISubDone();
     225    return rc;
     226}
     227
     228
     229/**
     230 * Testing some basics of the encrypted file VFS code.
     231 *
     232 * @returns nothing.
     233 * @param   pCryptoIf           Pointer to the callback table.
     234 */
     235static void tstCryptoVfsBasics(PCVBOXCRYPTOIF pCryptoIf)
     236{
     237    RTTestISub("Encrypted file - Basics");
     238
     239    RTTestDisableAssertions(g_hTest);
     240
     241    char *pszCtx = NULL;
     242    int rc = tstCryptoCtxCreate(pCryptoIf, g_aCiphers[4], g_szPassword, &pszCtx);
     243    if (RT_SUCCESS(rc))
     244    {
     245        /* Create the memory file to write to. */
     246        RTVFSFILE hVfsFile;
     247        rc = RTVfsMemFileCreate(NIL_RTVFSIOSTREAM, 0 /*cbEstimate*/, &hVfsFile);
     248        if (RT_SUCCESS(rc))
     249        {
     250            RTVFSFILE hVfsFileEnc;
     251
     252            RTTestISub("Creating encrypted file");
     253
     254            rc = pCryptoIf->pfnCryptoFileFromVfsFile(hVfsFile, pszCtx, g_szPassword, &hVfsFileEnc);
     255            if (RT_SUCCESS(rc))
     256            {
     257                RTTestISubDone();
     258
     259                size_t cbFile = RT_ALIGN_Z(RTRandU32Ex(_1K, 10 * _1M), sizeof(uint32_t)); /* Align to full counter field size. */
     260                rc = tstCryptoVfsWrite(hVfsFileEnc, cbFile);
     261                RTVfsFileRelease(hVfsFileEnc); /* Close file. */
     262                if (RT_SUCCESS(rc))
     263                {
     264                    /* Reopen for reading. */
     265                    RTTestISub("Open encrypted file");
     266
     267                    /* Reset the memory file offset. */
     268                    RTVfsFileSeek(hVfsFile, 0, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);
     269
     270                    rc = pCryptoIf->pfnCryptoFileFromVfsFile(hVfsFile, pszCtx, g_szPassword, &hVfsFileEnc);
     271                    if (RT_SUCCESS(rc))
     272                    {
     273                        RTTestISubDone();
     274
     275                        RTTestISub("Query encrypted file size");
     276                        uint64_t cbFileRd;
     277                        rc = RTVfsFileQuerySize(hVfsFileEnc, &cbFileRd);
     278                        if (RT_SUCCESS(rc))
     279                        {
     280                            if (cbFile != cbFileRd)
     281                                RTTestIFailed("Unexpected file size, got %#llx expected %#zx", cbFileRd, cbFile);
     282
     283                            RTTestISubDone();
     284                            tstCryptoVfsReadAndVerify(hVfsFileEnc, cbFile);
     285                        }
     286                        else
     287                            RTTestIFailed("Querying encrypted file size failed %Rrc", rc);
     288
     289                        RTVfsFileRelease(hVfsFileEnc); /* Close file. */
     290                    }
     291                    else
     292                        RTTestIFailed("Opening encrypted file for reading failed with %Rrc", rc);
     293
     294                }
     295                /* Error set on failure. */
     296            }
     297            else
     298                RTTestIFailed("Creating encrypted file handle failed with %Rrc", rc);
     299
     300            RTVfsFileRelease(hVfsFile);
     301        }
     302        else
     303            RTTestIFailed("Creating a new encrypted file failed with %Rrc", rc);
     304
     305        RTMemFree(pszCtx);
     306    }
     307    else
     308        RTTestIFailed("Creating a new encrypted context failed with %Rrc", rc);
     309
     310    RTTestRestoreAssertions(g_hTest);
     311    RTTestISubDone();
     312}
    54313
    55314
     
    147406                    /* Loading succeeded, now we can start real testing. */
    148407                    tstCryptoKeyStoreBasics(pCryptoIf);
     408                    tstCryptoVfsBasics(pCryptoIf);
    149409                }
    150410                else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette