Changeset 94743 in vbox
- Timestamp:
- Apr 28, 2022 6:00:37 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 151125
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/NvramStoreImpl.h
r94660 r94743 23 23 24 24 #include "NvramStoreWrap.h" 25 #include "SecretKeyStore.h" 25 26 #include <VBox/vmm/pdmdrv.h> 27 #include <VBox/VBoxCryptoIf.h> 28 26 29 27 30 #ifdef VBOX_COM_INPROC … … 82 85 #endif 83 86 87 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 84 88 HRESULT i_updateEncryptionSettings(const com::Utf8Str &strKeyId, 85 89 const com::Utf8Str &strKeyStore); … … 90 94 int i_removePassword(const Utf8Str &strKeyId); 91 95 int i_removeAllPasswords(); 96 #endif 92 97 93 98 private: 99 100 int initImpl(void); 94 101 95 102 // Wrapped NVRAM store properties … … 104 111 int i_loadStoreFromTar(RTVFSFSSTREAM hVfsFssTar); 105 112 int i_saveStoreAsTar(const char *pszPath); 113 114 int i_retainCryptoIf(PCVBOXCRYPTOIF *ppCryptoIf); 115 int i_releaseCryptoIf(PCVBOXCRYPTOIF pCryptoIf); 116 117 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 118 int i_setupEncryptionOrDecryption(RTVFSIOSTREAM hVfsIosInOut, bool fEncrypt, 119 PCVBOXCRYPTOIF *ppCryptoIf, SecretKey **ppKey, 120 PRTVFSIOSTREAM phVfsIos); 121 void i_releaseEncryptionOrDecryptionResources(RTVFSIOSTREAM hVfsIos, PCVBOXCRYPTOIF pCryptoIf, 122 SecretKey *pKey); 123 #endif 106 124 107 125 #ifdef VBOX_COM_INPROC -
trunk/src/VBox/Main/src-all/NvramStoreImpl.cpp
r94660 r94743 28 28 #endif 29 29 #include "UefiVariableStoreImpl.h" 30 #include "VirtualBoxImpl.h" 30 31 31 32 #include "AutoCaller.h" … … 97 98 #ifdef VBOX_COM_INPROC 98 99 , cRefs(0) 100 #endif 101 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 102 , mpKeyStore(NULL) 99 103 #endif 100 104 { } … … 117 121 #endif 118 122 123 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 124 /* Store for secret keys. */ 125 SecretKeyStore *mpKeyStore; 126 #endif 127 119 128 Backupable<BackupableNvramStoreData> bd; 120 129 }; … … 138 147 // public initializer/uninitializer for internal purposes only 139 148 ///////////////////////////////////////////////////////////////////////////// 149 150 /** 151 * Initialization stuff shared across the different methods. 152 * 153 * @returns COM result indicator 154 */ 155 int NvramStore::initImpl() 156 { 157 m = new Data(); 158 159 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 160 # ifdef VBOX_COM_INPROC 161 bool fNonPageable = true; 162 # else 163 /* Non-pageable memory is not accessible for non-VM process */ 164 bool fNonPageable = false; 165 # endif 166 167 m->mpKeyStore = new SecretKeyStore(fNonPageable /* fKeyBufNonPageable */); 168 AssertReturn(m->mpKeyStore, VERR_NO_MEMORY); 169 #endif 170 171 return VINF_SUCCESS; 172 } 173 140 174 141 175 #if !defined(VBOX_COM_INPROC) … … 156 190 AssertReturn(autoInitSpan.isOk(), E_FAIL); 157 191 158 m = new Data(); 192 int vrc = initImpl(); 193 if (RT_FAILURE(vrc)) 194 return E_FAIL; 159 195 160 196 /* share the parent weakly */ … … 188 224 AssertReturn(autoInitSpan.isOk(), E_FAIL); 189 225 190 m = new Data();226 initImpl(); 191 227 192 228 unconst(m->pParent) = aParent; … … 218 254 AssertReturn(autoInitSpan.isOk(), E_FAIL); 219 255 220 m = new Data();256 initImpl(); 221 257 222 258 unconst(m->pParent) = aParent; … … 251 287 AssertReturn(autoInitSpan.isOk(), E_FAIL); 252 288 253 m = new Data(); 289 initImpl(); 290 254 291 unconst(m->pParent) = aParent; 255 292 … … 292 329 293 330 m->bd->mapNvram.clear(); 331 332 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 333 if (m->mpKeyStore != NULL) 334 delete m->mpKeyStore; 335 #endif 294 336 295 337 delete m; … … 557 599 return rc; 558 600 } 601 602 603 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 604 /** 605 * Sets up the encryption or decryption machinery. 606 * 607 * @returns VBox status code. 608 * @param hVfsIosInOut Handle to the input stream to be decrypted or the destination to the encrypted 609 * output is written to. 610 * @param fEncrypt Flag whether to setup encryption or decryption. 611 * @param ppCryptoIf Where to store the pointer to the cryptographic interface which needs to be released 612 * when done. 613 * @param ppKey Where to store the pointer to the secret key buffer which needs to be released when done. 614 * @param phVfsIos Where to store the handle to the plaintext I/O stream (either input or output) on success. 615 */ 616 int NvramStore::i_setupEncryptionOrDecryption(RTVFSIOSTREAM hVfsIosInOut, bool fEncrypt, 617 PCVBOXCRYPTOIF *ppCryptoIf, SecretKey **ppKey, 618 PRTVFSIOSTREAM phVfsIos) 619 { 620 int rc = VINF_SUCCESS; 621 PCVBOXCRYPTOIF pCryptoIf = NULL; 622 SecretKey *pKey = NULL; 623 const char *pszPassword = NULL; 624 625 rc = i_retainCryptoIf(&pCryptoIf); 626 if (RT_SUCCESS(rc)) 627 { 628 rc = m->mpKeyStore->retainSecretKey(m->bd->strKeyId, &pKey); 629 if (RT_SUCCESS(rc)) 630 { 631 pszPassword = (const char *)pKey->getKeyBuffer(); 632 if (fEncrypt) 633 rc = pCryptoIf->pfnCryptoIoStrmFromVfsIoStrmEncrypt(hVfsIosInOut, m->bd->strKeyStore.c_str(), pszPassword, 634 phVfsIos); 635 else 636 rc = pCryptoIf->pfnCryptoIoStrmFromVfsIoStrmDecrypt(hVfsIosInOut, m->bd->strKeyStore.c_str(), pszPassword, 637 phVfsIos); 638 if (RT_SUCCESS(rc)) 639 { 640 *ppCryptoIf = pCryptoIf; 641 *ppKey = pKey; 642 return VINF_SUCCESS; 643 } 644 else 645 LogRelMax(10, ("Failed to decrypt the NVRAM store using secret key ID '%s' with %Rrc\n", 646 m->bd->strKeyId.c_str(), rc)); 647 648 m->mpKeyStore->releaseSecretKey(m->bd->strKeyId); 649 } 650 else 651 LogRelMax(10, ("Failed to retain the secret key ID '%s' with %Rrc\n", 652 m->bd->strKeyId.c_str(), rc)); 653 654 i_releaseCryptoIf(pCryptoIf); 655 } 656 else 657 LogRelMax(10, ("Failed to retain the cryptographic interface with %Rrc\n", rc)); 658 659 return rc; 660 } 661 662 /** 663 * Releases all resources acquired in NvramStore::i_setupEncryptionOrDecryption(). 664 * 665 * @returns nothing. 666 * @param hVfsIos Handle to the I/O stream previously created. 667 * @param pCryptoIf Pointer to the cryptographic interface being released. 668 * @param pKey Pointer to the key buffer being released. 669 */ 670 void NvramStore::i_releaseEncryptionOrDecryptionResources(RTVFSIOSTREAM hVfsIos, PCVBOXCRYPTOIF pCryptoIf, 671 SecretKey *pKey) 672 { 673 Assert(hVfsIos != NIL_RTVFSIOSTREAM); 674 AssertPtr(pCryptoIf); 675 AssertPtr(pKey); 676 677 i_releaseCryptoIf(pCryptoIf); 678 m->mpKeyStore->releaseSecretKey(m->bd->strKeyId); 679 RTVfsIoStrmRelease(hVfsIos); 680 } 681 #endif 559 682 560 683 … … 586 709 if (RT_SUCCESS(rc)) 587 710 { 588 /* Read the content. */ 589 RTVFSFILE hVfsFileNvram; 590 rc = RTVfsMemorizeIoStreamAsFile(hVfsIosNvram, RTFILE_O_READ, &hVfsFileNvram); 711 RTVFSIOSTREAM hVfsIosDecrypted = NIL_RTVFSIOSTREAM; 712 713 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 714 PCVBOXCRYPTOIF pCryptoIf = NULL; 715 SecretKey *pKey = NULL; 716 717 if ( m->bd->strKeyId.isNotEmpty() 718 && m->bd->strKeyStore.isNotEmpty()) 719 rc = i_setupEncryptionOrDecryption(hVfsIosNvram, false /*fEncrypt*/, 720 &pCryptoIf, &pKey, &hVfsIosDecrypted); 721 #endif 591 722 if (RT_SUCCESS(rc)) 592 723 { 593 /* Try to parse it as an EFI variable store. */ 594 RTVFS hVfsEfiVarStore; 595 rc = RTEfiVarStoreOpenAsVfs(hVfsFileNvram, RTVFSMNT_F_READ_ONLY, 0 /*fVarStoreFlags*/, &hVfsEfiVarStore, 596 NULL /*pErrInfo*/); 724 /* Read the content. */ 725 RTVFSFILE hVfsFileNvram; 726 rc = RTVfsMemorizeIoStreamAsFile( hVfsIosDecrypted != NIL_RTVFSIOSTREAM 727 ? hVfsIosDecrypted 728 : hVfsIosNvram, 729 RTFILE_O_READ, &hVfsFileNvram); 597 730 if (RT_SUCCESS(rc)) 598 731 { 599 rc = RTVfsFileSeek(hVfsFileNvram, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);600 AssertRC(rc);601 602 RTVfsFileRetain(hVfsFileNvram); /* Retain a new reference for the map. */603 m->bd->mapNvram[Utf8Str("efi/nvram")] = hVfsFileNvram;604 605 RTVfsRelease(hVfsEfiVarStore);606 }607 else if (rc == VERR_VFS_UNKNOWN_FORMAT)608 {609 /* Check for the new style tar archive. */610 rc = RTVfsFileSeek(hVfsFileNvram, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);611 AssertRC(rc);612 613 RTVFSIOSTREAM hVfsIosTar = RTVfsFileToIoStream(hVfsFileNvram);614 Assert(hVfsIosTar != NIL_RTVFSIOSTREAM);615 616 RTVFSFSSTREAM hVfsFssTar;617 rc = RTZipTarFsStreamFromIoStream(hVfsIosTar, 0 /*fFlags*/, &hVfsFssTar);618 RTVfsIoStrmRelease(hVfsIosTar);619 732 if (RT_SUCCESS(rc)) 620 733 { 621 rc = i_loadStoreFromTar(hVfsFssTar); 622 RTVfsFsStrmRelease(hVfsFssTar); 734 /* Try to parse it as an EFI variable store. */ 735 RTVFS hVfsEfiVarStore; 736 rc = RTEfiVarStoreOpenAsVfs(hVfsFileNvram, RTVFSMNT_F_READ_ONLY, 0 /*fVarStoreFlags*/, &hVfsEfiVarStore, 737 NULL /*pErrInfo*/); 738 if (RT_SUCCESS(rc)) 739 { 740 rc = RTVfsFileSeek(hVfsFileNvram, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/); 741 AssertRC(rc); 742 743 RTVfsFileRetain(hVfsFileNvram); /* Retain a new reference for the map. */ 744 m->bd->mapNvram[Utf8Str("efi/nvram")] = hVfsFileNvram; 745 746 RTVfsRelease(hVfsEfiVarStore); 747 } 748 else if (rc == VERR_VFS_UNKNOWN_FORMAT) 749 { 750 /* Check for the new style tar archive. */ 751 rc = RTVfsFileSeek(hVfsFileNvram, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/); 752 AssertRC(rc); 753 754 RTVFSIOSTREAM hVfsIosTar = RTVfsFileToIoStream(hVfsFileNvram); 755 Assert(hVfsIosTar != NIL_RTVFSIOSTREAM); 756 757 RTVFSFSSTREAM hVfsFssTar; 758 rc = RTZipTarFsStreamFromIoStream(hVfsIosTar, 0 /*fFlags*/, &hVfsFssTar); 759 RTVfsIoStrmRelease(hVfsIosTar); 760 if (RT_SUCCESS(rc)) 761 { 762 rc = i_loadStoreFromTar(hVfsFssTar); 763 RTVfsFsStrmRelease(hVfsFssTar); 764 } 765 else 766 LogRel(("The given NVRAM file is neither a raw UEFI variable store nor a tar archive (opening failed with %Rrc)\n", rc)); 767 } 768 else 769 LogRel(("Opening the UEFI variable store '%s' failed with %Rrc\n", pszPath, rc)); 770 771 RTVfsFileRelease(hVfsFileNvram); 623 772 } 624 773 else 625 LogRel((" The given NVRAM file is neither a raw UEFI variable store nor a tar archive (opening failed with %Rrc)\n", rc));774 LogRel(("Failed to memorize NVRAM store '%s' with %Rrc\n", pszPath, rc)); 626 775 } 627 else628 LogRel(("Opening the UEFI variable store '%s' failed with %Rrc\n", pszPath, rc));629 630 RTVfsFileRelease(hVfsFileNvram);631 776 } 632 else 633 LogRel(("Failed to memorize NVRAM store '%s' with %Rrc\n", pszPath, rc)); 777 778 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 779 if (hVfsIosDecrypted != NIL_RTVFSIOSTREAM) 780 i_releaseEncryptionOrDecryptionResources(hVfsIosDecrypted, pCryptoIf, pKey); 781 #endif 634 782 635 783 RTVfsIoStrmRelease(hVfsIosNvram); … … 662 810 if (RT_SUCCESS(rc)) 663 811 { 664 RTVFSFSSTREAM hVfsFss; 665 rc = RTZipTarFsStreamToIoStream(hVfsIos, RTZIPTARFORMAT_GNU, 0 /*fFlags*/, &hVfsFss); 812 RTVFSIOSTREAM hVfsIosEncrypted = NIL_RTVFSIOSTREAM; 813 814 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 815 PCVBOXCRYPTOIF pCryptoIf = NULL; 816 SecretKey *pKey = NULL; 817 818 if ( m->bd->strKeyId.isNotEmpty() 819 && m->bd->strKeyStore.isNotEmpty()) 820 rc = i_setupEncryptionOrDecryption(hVfsIos, true /*fEncrypt*/, 821 &pCryptoIf, &pKey, &hVfsIosEncrypted); 822 #endif 823 666 824 if (RT_SUCCESS(rc)) 667 825 { 668 NvramStoreIter it = m->bd->mapNvram.begin(); 669 670 while (it != m->bd->mapNvram.end()) 826 RTVFSFSSTREAM hVfsFss; 827 rc = RTZipTarFsStreamToIoStream( hVfsIosEncrypted != NIL_RTVFSIOSTREAM 828 ? hVfsIosEncrypted 829 : hVfsIos, 830 RTZIPTARFORMAT_GNU, 0 /*fFlags*/, &hVfsFss); 831 if (RT_SUCCESS(rc)) 671 832 { 672 RTVFSFILE hVfsFile = it->second; 673 674 rc = RTVfsFileSeek(hVfsFile, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/); 675 AssertRC(rc); 676 677 RTVFSOBJ hVfsObj = RTVfsObjFromFile(hVfsFile); 678 rc = RTVfsFsStrmAdd(hVfsFss, it->first.c_str(), hVfsObj, 0 /*fFlags*/); 679 RTVfsObjRelease(hVfsObj); 680 if (RT_FAILURE(rc)) 681 break; 682 683 it++; 833 NvramStoreIter it = m->bd->mapNvram.begin(); 834 835 while (it != m->bd->mapNvram.end()) 836 { 837 RTVFSFILE hVfsFile = it->second; 838 839 rc = RTVfsFileSeek(hVfsFile, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/); 840 AssertRC(rc); 841 842 RTVFSOBJ hVfsObj = RTVfsObjFromFile(hVfsFile); 843 rc = RTVfsFsStrmAdd(hVfsFss, it->first.c_str(), hVfsObj, 0 /*fFlags*/); 844 RTVfsObjRelease(hVfsObj); 845 if (RT_FAILURE(rc)) 846 break; 847 848 it++; 849 } 850 851 RTVfsFsStrmRelease(hVfsFss); 684 852 } 685 853 686 RTVfsFsStrmRelease(hVfsFss); 854 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 855 if (hVfsIosEncrypted != NIL_RTVFSIOSTREAM) 856 i_releaseEncryptionOrDecryptionResources(hVfsIosEncrypted, pCryptoIf, pKey); 857 #endif 687 858 } 688 859 … … 691 862 692 863 return rc; 864 } 865 866 867 int NvramStore::i_retainCryptoIf(PCVBOXCRYPTOIF *ppCryptoIf) 868 { 869 #ifdef VBOX_COM_INPROC 870 return m->pParent->i_retainCryptoIf(ppCryptoIf); 871 #else 872 return m->pParent->i_getVirtualBox()->i_retainCryptoIf(ppCryptoIf); 873 #endif 874 } 875 876 877 int NvramStore::i_releaseCryptoIf(PCVBOXCRYPTOIF pCryptoIf) 878 { 879 #ifdef VBOX_COM_INPROC 880 return m->pParent->i_releaseCryptoIf(pCryptoIf); 881 #else 882 return m->pParent->i_getVirtualBox()->i_releaseCryptoIf(pCryptoIf); 883 #endif 693 884 } 694 885 … … 735 926 Assert(hVfsIosSrc != NIL_RTVFSIOSTREAM); 736 927 737 rc = RTVfsUtilPumpIoStreams(hVfsIosSrc, hVfsIosDst, 0 /*cbBufHint*/); 928 RTVFSIOSTREAM hVfsIosEncrypted = NIL_RTVFSIOSTREAM; 929 930 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 931 PCVBOXCRYPTOIF pCryptoIf = NULL; 932 SecretKey *pKey = NULL; 933 934 if ( m->bd->strKeyId.isNotEmpty() 935 && m->bd->strKeyStore.isNotEmpty()) 936 rc = i_setupEncryptionOrDecryption(hVfsIosDst, true /*fEncrypt*/, 937 &pCryptoIf, &pKey, &hVfsIosEncrypted); 938 #endif 939 940 rc = RTVfsUtilPumpIoStreams(hVfsIosSrc, 941 hVfsIosEncrypted != NIL_RTVFSIOSTREAM 942 ? hVfsIosEncrypted 943 : hVfsIosDst 944 , 0 /*cbBufHint*/); 945 946 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 947 if (hVfsIosEncrypted != NIL_RTVFSIOSTREAM) 948 i_releaseEncryptionOrDecryptionResources(hVfsIosEncrypted, pCryptoIf, pKey); 949 #endif 738 950 739 951 RTVfsIoStrmRelease(hVfsIosSrc); … … 748 960 return rc; 749 961 } 962 963 964 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 965 HRESULT NvramStore::i_updateEncryptionSettings(const com::Utf8Str &strKeyId, 966 const com::Utf8Str &strKeyStore) 967 { 968 /* sanity */ 969 AutoCaller autoCaller(this); 970 AssertComRCReturnRC(autoCaller.rc()); 971 972 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 973 974 m->bd.backup(); 975 m->bd->strKeyId = strKeyId; 976 m->bd->strKeyStore = strKeyStore; 977 978 /* clear all passwords because they are invalid now */ 979 m->mpKeyStore->deleteAllSecretKeys(false, true); 980 981 alock.release(); 982 AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS); 983 #ifndef VBOX_COM_INPROC 984 m->pParent->i_setModified(Machine::IsModified_NvramStore); 985 #endif 986 return S_OK; 987 } 988 989 990 HRESULT NvramStore::i_getEncryptionSettings(com::Utf8Str &strKeyId, 991 com::Utf8Str &strKeyStore) 992 { 993 AutoCaller autoCaller(this); 994 AssertComRCReturnRC(autoCaller.rc()); 995 996 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 997 998 strKeyId = m->bd->strKeyId; 999 strKeyStore = m->bd->strKeyStore; 1000 1001 return S_OK; 1002 } 1003 1004 1005 int NvramStore::i_addPassword(const Utf8Str &strKeyId, const Utf8Str &strPassword) 1006 { 1007 AutoCaller autoCaller(this); 1008 AssertComRCReturnRC(autoCaller.rc()); 1009 1010 /* keep only required password */ 1011 if (strKeyId != m->bd->strKeyId) 1012 return VINF_SUCCESS; 1013 1014 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1015 return m->mpKeyStore->addSecretKey(strKeyId, (const uint8_t *)strPassword.c_str(), strPassword.length() + 1); 1016 } 1017 1018 1019 int NvramStore::i_removePassword(const Utf8Str &strKeyId) 1020 { 1021 AutoCaller autoCaller(this); 1022 AssertComRCReturnRC(autoCaller.rc()); 1023 1024 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1025 return m->mpKeyStore->deleteSecretKey(strKeyId); 1026 } 1027 1028 1029 int NvramStore::i_removeAllPasswords() 1030 { 1031 AutoCaller autoCaller(this); 1032 AssertComRCReturnRC(autoCaller.rc()); 1033 1034 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1035 m->mpKeyStore->deleteAllSecretKeys(false, true); 1036 return VINF_SUCCESS; 1037 } 1038 #endif 750 1039 751 1040 … … 809 1098 810 1099 m->bd->strNvramPath = data.strNvramPath; 1100 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 1101 m->bd->strKeyId = data.strKeyId; 1102 m->bd->strKeyStore = data.strKeyStore; 1103 #endif 811 1104 812 1105 Utf8Str strTmp(m->bd->strNvramPath); … … 835 1128 836 1129 data.strNvramPath = m->bd->strNvramPath; 1130 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 1131 data.strKeyId = m->bd->strKeyId; 1132 data.strKeyStore = m->bd->strKeyStore; 1133 #endif 837 1134 838 1135 int vrc = i_saveStore();
Note:
See TracChangeset
for help on using the changeset viewer.