Fluidsynth How to encrypt\Decrypt a soundfont ? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Fluidsynth How to encrypt\Decrypt a soundfont ?

25 Oct 2020, 15:31

Now I know that to load a soundfont with Fluidsynth we use the following:
DllCall(FSynth_dll "\fluid_synth_sfload", "Ptr", synth, "AStr", "GeneralUser.sf2", "Int", true)

My idea, in order to protect my SoundFont, was to:
- encrypt it using any encryption method
- save the SoundFont as a .dat file on the hard drive
- fileread, encryptedSoundfont, c:\soundfont.dat
- Decrypt the encryptedSoundfont to a var decryptedSoundfont
and
DllCall(FSynth_dll "\fluid_synth_sfload", "Ptr", synth, decryptedSoundfont, "Int", False)

unfortunately, that didn't work.

Did I oversimplified things?
Can it be done? how?
Any idea?

I found this snippet in a Fluidsynth documentation:

char abused_filename[64];
sprintf(abused_filename, "&%p", pointer_to_sf2_in_mem);
fluid_synth_sfload(synth, abused_filename, FALSE);

can it translate to Autohotkey?

Thank you.
Last edited by keylo on 26 Oct 2020, 19:18, edited 1 time in total.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Fluidsynth How to Load my encrypted soundfont ?

25 Oct 2020, 18:03

continuation of the last example with the same prerequisites, again no cleanup(fluid_delete_..., GlobalFree) or error checking:

Code: Select all

#NoEnv
#SingleInstance Force
SendMode Input
SetBatchLines -1
SetTitleMatchMode 2
SetWorkingDir % A_ScriptDir

global FLUID_OK := 0

hModule := DllCall("LoadLibrary", "Str", dll := "libfluidsynth-2.dll", "Ptr")

settings := DllCall(dll "\new_fluid_settings", "Ptr")
synth := DllCall(dll "\new_fluid_synth", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_settings_setstr", "Ptr", settings, "AStr", "audio.driver", "AStr", "waveout")
adriver := DllCall(dll "\new_fluid_audio_driver", "Ptr", settings, "Ptr", synth, "Ptr")

my_sfloader := DllCall(dll "\new_fluid_defsfloader", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_sfloader_set_callbacks"
	, "Ptr", my_sfloader
	, "Ptr", RegisterCallback("my_open")
	, "Ptr", RegisterCallback("my_read")
	, "Ptr", RegisterCallback("my_seek")
	, "Ptr", RegisterCallback("my_tell")
	, "Ptr", RegisterCallback("my_close"))

DllCall(dll "\fluid_synth_add_sfloader", "Ptr", synth, "Ptr", my_sfloader)
id := DllCall(dll "\fluid_synth_sfload", "Ptr", synth, "AStr", "GeneralUser GS v1.471.sf2", "Int", true)

q::
	DllCall(dll "\fluid_synth_noteon", "Ptr", synth, "Int", 0, "Int", 60, "Int", 100)
	KeyWait % A_ThisHotkey
	DllCall(dll "\fluid_synth_noteoff", "Ptr", synth, "Int", 0, "Int", 60)
return

Esc::ExitApp

my_open(lpszFilename) {
	filename := StrGet(lpszFilename, "CP0")

	f := FileOpen(filename, "r")
	hSoundfont := DllCall("GlobalAlloc", "UInt", 0, "Ptr", f.Length, "Ptr")
	f.RawRead(hSoundfont, f.Length)
	
	; optional decryption here
	
	return hSoundfont
}

my_read(buf, count, handle) {
	; NYI
	return FLUID_OK
}

my_seek(handle, offset, origin) {
	; NYI
	return FLUID_OK
}

my_close(handle) {
	; NYI
	return FLUID_OK
}

my_tell(handle) {
	; NYI
	return 0
}
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Re: Fluidsynth How to Load my encrypted soundfont ?

25 Oct 2020, 18:54

Thank you @Swagfag, I like the way you keep it simple and straightforward.
I'm doing some tests, very promising. :clap:
Your knowledge on the Dllcalls amazes me, Thankyou for sharing.
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Re: Fluidsynth How to Load my encrypted soundfont ?

25 Oct 2020, 21:26

I was not able to make it work.

I'm not sure where to put the path for my encrypted file
and I don't understand why we still need:
id := DllCall(dll "\fluid_synth_sfload", "Ptr", synth, "AStr", "GeneralUser.sf2", "Int", true)
if we are using:
DllCall(dll "\fluid_synth_add_sfloader", "Ptr", synth, "Ptr", my_sfloader)

Of course, I'm trying to work without any encryption first.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Fluidsynth How to Load my encrypted soundfont ?

25 Oct 2020, 21:41

u need fluid_synth_sfload because thats the function that issues the command to start loading soundfonts
the other function only changes the loading settings, but doesnt do any actual loading

also, u dont need to specify a filepath. u could load the soundfont's bytes urself, decrypt them, then pass the pointer to the decrypted bytes to fluid_synth_sfload(but it has to be done as though the pointer were an ANSI string!, since FLUIDSYNTH_API int fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets))
then in the open callback, simply return the pointer that u originally passed in, something like:

Code: Select all

my_open(lpszSomeDecodedBytes) {
	return StrGet(lpszSomeDecodedBytes, "CP0")
}
Last edited by swagfag on 26 Oct 2020, 08:49, edited 1 time in total.
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Re: Fluidsynth How to Load my encrypted soundfont ?

26 Oct 2020, 08:42

Thank you Swagfag, it is more clear to me now. but I still can't fully test it since I have not yet find the best and fastest way to encrypt and decrypt.

I tried with function: RC4hex2txt(Data,Pass) , that didn't work.

I will try a function call Base64enc\Base64dec.
But if you have any suggestion you are more than welcome. ;)
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Re: Fluidsynth How to encrypt\Decrypt a soundfont ?

27 Oct 2020, 02:17

I found how to encrypt and decrypt my soundfont with a function called Crypt_AES. But I still don't understand how to get Fluidsynth to load my decrypted soundfont.

I keep getting error : Not a RIFF file and Invalid Riff chunk ID :think:

Here is the code so far:

Code: Select all

#NoEnv
#SingleInstance Force
SendMode Input
SetBatchLines -1
SetTitleMatchMode 2
SetWorkingDir % A_ScriptDir

global FLUID_OK := 0

hModule := DllCall("LoadLibrary", "Str", dll := "libfluidsynth-2.dll", "Ptr")

settings := DllCall(dll "\new_fluid_settings", "Ptr")
synth := DllCall(dll "\new_fluid_synth", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_settings_setstr", "Ptr", settings, "AStr", "audio.driver", "AStr", "waveout")
adriver := DllCall(dll "\new_fluid_audio_driver", "Ptr", settings, "Ptr", synth, "Ptr")

my_sfloader := DllCall(dll "\new_fluid_defsfloader", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_sfloader_set_callbacks"
	, "Ptr", my_sfloader
	, "Ptr", RegisterCallback("my_open")
	, "Ptr", RegisterCallback("my_read")
	, "Ptr", RegisterCallback("my_seek")
	, "Ptr", RegisterCallback("my_tell")
	, "Ptr", RegisterCallback("my_close"))

DllCall(dll "\fluid_synth_add_sfloader", "Ptr", synth, "Ptr", my_sfloader)
id := DllCall(dll "\fluid_synth_sfload", "Ptr", synth, "AStr", "encrypted.sf2", "Int", true)


q::
	DllCall(dll "\fluid_synth_noteon", "Ptr", synth, "Int", 0, "Int", 60, "Int", 100)
	KeyWait % A_ThisHotkey
	DllCall(dll "\fluid_synth_noteoff", "Ptr", synth, "Int", 0, "Int", 60)
return

Esc::ExitApp




my_open(lpszFilename) {
	filename := StrGet(lpszFilename, "CP0")
	f := FileOpen(filename, "r")

	hSoundfont := DllCall("GlobalAlloc", "UInt", 0, "Ptr", f.Length, "Ptr")
	f.RawRead(hSoundfont, f.Length)


;~ Decrypting
 Crypt_AES(&hSoundfont, f.Length, "mypassword", 256, False)

return hSoundfont

}

my_read(buf, count, handle) {
	; NYI
	return FLUID_OK
}

my_seek(handle, offset, origin) {
	; NYI
	return FLUID_OK
}

my_close(handle) {
	; NYI
	return FLUID_OK
}

my_tell(handle) {
	; NYI
	return 0
}

;~ *********************************************************
;~ https://autohotkey.com/board/topic/76530-how-do-i-use-seans-aes-encryptdecrypt-library/
File_AES(sFileFr, sFileTo, sPassword, SID = 256, bEncrypt = True)
{
   hFileFr := FileOpen(sFileFr,"r -r")
   if not hFileFr
      Return   "File not found!"
   nSize := hFileFr.Length
   VarSetCapacity(sData, nSize + (bEncrypt ? 16 : 0))
   hFileFr.Seek(0)
   hFileFr.RawRead(sData, nSize)
   hFileFr.Close()
   hFileTo := FileOpen(sFileTo,"w -r")
   if not hFileTo
      Return   "File not created/opened!"
   nSize := Crypt_AES(&sData, nSize, sPassword, SID, bEncrypt)
   hFileTo.RawWrite(sData, nSize)
   hFileTo.Close()
      Return   nSize
}
Crypt_AES(pData, nSize, sPassword, SID = 256, bEncrypt = True)
{
   CALG_AES_256 := 1 + CALG_AES_192 := 1 + CALG_AES_128 := 0x660E
   CALG_SHA1 := 1 + CALG_MD5 := 0x8003
   DllCall("advapi32\CryptAcquireContext", "UPtr*", hProv, "UPtr", 0, "UPtr", 0, "UPtr", 24, "UPtr", 0xF0000000)
   DllCall("advapi32\CryptCreateHash", "UPtr", hProv, "UPtr", CALG_SHA1, "UPtr", 0, "UPtr", 0, "UPtr*", hHash)
   DllCall("advapi32\CryptHashData", "UPtr", hHash
   , "UPtr", &sPassword
   , "UPtr", (A_IsUnicode ? StrLen(sPassword)*2 : StrLen(sPassword)), "UPtr", 0)
   DllCall("advapi32\CryptDeriveKey", "UPtr", hProv, "UPtr", CALG_AES_%SID%, "UPtr", hHash, "UPtr", SID<<16, "UPtr*", hKey)
   DllCall("advapi32\CryptDestroyHash", "UPtr", hHash)
   bEncrypt
   ? DllCall("advapi32\CryptEncrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize, "UPtr", nSize+16)
   : DllCall("advapi32\CryptDecrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize)
   DllCall("advapi32\CryptDestroyKey", "UPtr", hKey)
   DllCall("advapi32\CryptReleaseContext", "UPtr", hProv, "UPtr", 0)
   Return   nSize
}
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Fluidsynth How to encrypt\Decrypt a soundfont ?

27 Oct 2020, 05:04

Code: Select all

hSoundfont := DllCall("GlobalAlloc", "UInt", 0, "Ptr", f.Length, "Ptr")
f.RawRead(hSoundfont, f.Length)
Crypt_AES(&hSoundfont,
delete the &
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Re: Fluidsynth How to encrypt\Decrypt a soundfont ?

27 Oct 2020, 07:35

No, that didn't work. Fluidsynth seems to give prioritize the loading of the SoundFont file on the hard drive and ignore everything (decryption) that is done in " My_open()" function.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Fluidsynth How to encrypt\Decrypt a soundfont ?

27 Oct 2020, 09:43

Code: Select all

hSoundfont := DllCall("GlobalAlloc", "UInt", 0, "Ptr", f.Length, "Ptr")
f.RawRead(hSoundfont+0, f.Length)
Crypt_AES(hSoundfont,
and also a mathematical operation needs to be performed on hSoundfont due to ahk limitations
numget wrote:Do not pass a variable reference if the variable contains the target address; in that case, pass an expression such as MyVar+0.
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Re: Fluidsynth How to encrypt\Decrypt a soundfont ?

27 Oct 2020, 19:01

I tried that and several other things, I still cannot get it to work.
The fact is that my knowledge of pointers and memory reading is very limited, but I don't give up.

Now I know how to encrypt and decrypt a soundfont file with Crypt_AES ( tested and working find)

What I am missing is the way to make fluidsynth load my decrypted soundfont in the memory
this is what I tried:

Code: Select all




 ;~ Reading and decrypting the soundfont
FileRead, data, *c %A_ScriptDir%\encrypted.sf2
size := StrLen(data)
Crypt_AES(data, size, "mypassword", 256, False)
;~ ************************


global FLUID_OK := 0

hModule := DllCall("LoadLibrary", "Str", dll := "libfluidsynth-2.dll", "Ptr")

settings := DllCall(dll "\new_fluid_settings", "Ptr")
synth := DllCall(dll "\new_fluid_synth", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_settings_setstr", "Ptr", settings, "AStr", "audio.driver", "AStr", "waveout")
adriver := DllCall(dll "\new_fluid_audio_driver", "Ptr", settings, "Ptr", synth, "Ptr")

my_sfloader := DllCall(dll "\new_fluid_defsfloader", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_sfloader_set_callbacks"
	, "Ptr", my_sfloader
	, "Ptr", RegisterCallback("my_open")
	, "Ptr", RegisterCallback("my_read")
	, "Ptr", RegisterCallback("my_seek")
	, "Ptr", RegisterCallback("my_tell")
	, "Ptr", RegisterCallback("my_close"))

DllCall(dll "\fluid_synth_add_sfloader", "Ptr", synth, "Ptr", my_sfloader)

;~ *****************
;~ >>>>>>>This is were I'm stuck, I don't know how to enter the pointer to my decrypted soundfont <<<<<<<<<<<<<<<<
/*
as per FluidSynth documentation : http www.fluidsynth.org /api/fluidsynth_sfload_mem_8c-example.html#a5  Broken Link for safety

    char abused_filename[64];
    const void *pointer_to_sf2_in_mem = 0x1234Beef; // some pointer to where the soundfont shall be loaded from
    sprintf(abused_filename, "&%p", pointer_to_sf2_in_mem);
    int id = fluid_synth_sfload(synth, abused_filename, 0);
	*/
;~ *****************
id := DllCall(dll "\fluid_synth_sfload", "Ptr", synth, "astr" ,??????, "Int", true)
;~ *****************
;~ *****************


q::
	DllCall(dll "\fluid_synth_noteon", "Ptr", synth, "Int", 0, "Int", 60, "Int", 100)
	KeyWait % A_ThisHotkey
	DllCall(dll "\fluid_synth_noteoff", "Ptr", synth, "Int", 0, "Int", 60)
return

Esc::ExitApp




my_open(lpszFilename) {
	filename := StrGet(lpszFilename, "CP0")
	f := FileOpen(filename, "r")
	hSoundfont := DllCall("GlobalAlloc", "UInt", 0, "Ptr", f.Length, "Ptr")
     
	f.RawRead(hSoundfont+0, f.Length)
	
    Crypt_AES(hSoundfont, f.Length, "mypassword", 256, False)


 
return hSoundfont

}

my_read(buf, count, handle) {
	; NYI
	return FLUID_OK
}

my_seek(handle, offset, origin) {
	; NYI
	return FLUID_OK
}

my_close(handle) {
	; NYI
	return FLUID_OK
}

my_tell(handle) {
	; NYI
	return 0
}








swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Fluidsynth How to encrypt\Decrypt a soundfont ?  Topic is solved

28 Oct 2020, 07:47

looks like the remaining file callbacks have to be implemented as well

Code: Select all

#NoEnv
#SingleInstance Force
SendMode Input
SetBatchLines -1
SetTitleMatchMode 2
SetWorkingDir % A_ScriptDir

global FLUID_OK := 0, FLUID_FAILED := -1

hModule := DllCall("LoadLibrary", "Str", dll := "libfluidsynth-2.dll", "Ptr")

settings := DllCall(dll "\new_fluid_settings", "Ptr")
synth := DllCall(dll "\new_fluid_synth", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_settings_setstr", "Ptr", settings, "AStr", "audio.driver", "AStr", "waveout")
adriver := DllCall(dll "\new_fluid_audio_driver", "Ptr", settings, "Ptr", synth, "Ptr")

my_sfloader := DllCall(dll "\new_fluid_defsfloader", "Ptr", settings, "Ptr")
DllCall(dll "\fluid_sfloader_set_callbacks"
	, "Ptr", my_sfloader
	, "Ptr", RegisterCallback("my_open")
	, "Ptr", RegisterCallback("my_read")
	, "Ptr", RegisterCallback("my_seek")
	, "Ptr", RegisterCallback("my_tell")
	, "Ptr", RegisterCallback("my_close"))

DllCall(dll "\fluid_synth_add_sfloader", "Ptr", synth, "Ptr", my_sfloader)

pass := "mypassword"
if !FileExist("encrypted.sf2")
	File_AES("GeneralUser GS v1.471.sf2", "encrypted.sf2", pass)

;~ Reading and decrypting the soundfont
FileRead, data, *c %A_ScriptDir%\encrypted.sf2
FileGetSize encryptedSize, encrypted.sf2
global decryptedSize := Crypt_AES(&data, encryptedSize, pass, 256, False)
global pos := 0
;~ ************************
id := DllCall(dll "\fluid_synth_sfload", "Ptr", synth, "AStr", "&" &data, "Int", true)

q::
	DllCall(dll "\fluid_synth_noteon", "Ptr", synth, "Int", 0, "Int", 60, "Int", 100)
	KeyWait % A_ThisHotkey
	DllCall(dll "\fluid_synth_noteoff", "Ptr", synth, "Int", 0, "Int", 60)
return

Esc::ExitApp

my_open(lpszFilename) {
	filename := StrGet(lpszFilename, "CP0")

	if (SubStr(filename, 1, 1) != "&")
		return 0

	p := SubStr(filename, 2)

	return p
}

my_read(buf, count, handle) {
	DllCall("RtlCopyMemory", "Ptr", buf, "Ptr", handle + pos, "Ptr", count)
	pos += count

	return FLUID_OK
}

my_seek(handle, offset, origin) {
	switch origin
	{
	case 0: pos := offset ; SEEK_SET
	case 1: pos += offset ; SEEK_CUR
	case 2: pos := decryptedSize + offset ; SEEK_END
	}

	if (pos < 0 || pos > decryptedSize)
		return FLUID_FAILED

	return FLUID_OK
}

my_close(handle) {
	return FLUID_OK
}

my_tell(handle) {
	return pos
}

;~ *********************************************************
;~ https://autohotkey.com/board/topic/76530-how-do-i-use-seans-aes-encryptdecrypt-library/
File_AES(sFileFr, sFileTo, sPassword, SID = 256, bEncrypt = True)
{
   hFileFr := FileOpen(sFileFr,"r -r")
   if not hFileFr
      Return   "File not found!"
   nSize := hFileFr.Length
   VarSetCapacity(sData, nSize + (bEncrypt ? 16 : 0))
   hFileFr.Seek(0)
   hFileFr.RawRead(sData, nSize)
   hFileFr.Close()
   hFileTo := FileOpen(sFileTo,"w -r")
   if not hFileTo
      Return   "File not created/opened!"
   nSize := Crypt_AES(&sData, nSize, sPassword, SID, bEncrypt)
   hFileTo.RawWrite(sData, nSize)
   hFileTo.Close()
      Return   nSize
}
Crypt_AES(pData, nSize, sPassword, SID = 256, bEncrypt = True)
{
   CALG_AES_256 := 1 + CALG_AES_192 := 1 + CALG_AES_128 := 0x660E
   CALG_SHA1 := 1 + CALG_MD5 := 0x8003
   DllCall("advapi32\CryptAcquireContext", "UPtr*", hProv, "UPtr", 0, "UPtr", 0, "UPtr", 24, "UPtr", 0xF0000000)
   DllCall("advapi32\CryptCreateHash", "UPtr", hProv, "UPtr", CALG_SHA1, "UPtr", 0, "UPtr", 0, "UPtr*", hHash)
   DllCall("advapi32\CryptHashData", "UPtr", hHash
   , "UPtr", &sPassword
   , "UPtr", (A_IsUnicode ? StrLen(sPassword)*2 : StrLen(sPassword)), "UPtr", 0)
   DllCall("advapi32\CryptDeriveKey", "UPtr", hProv, "UPtr", CALG_AES_%SID%, "UPtr", hHash, "UPtr", SID<<16, "UPtr*", hKey)
   DllCall("advapi32\CryptDestroyHash", "UPtr", hHash)
   bEncrypt
   ? DllCall("advapi32\CryptEncrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize, "UPtr", nSize+16)
   : DllCall("advapi32\CryptDecrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize)
   DllCall("advapi32\CryptDestroyKey", "UPtr", hKey)
   DllCall("advapi32\CryptReleaseContext", "UPtr", hProv, "UPtr", 0)
   Return   nSize
}
keylo
Posts: 51
Joined: 21 Oct 2020, 21:03

Re: Fluidsynth How to encrypt\Decrypt a soundfont ?

28 Oct 2020, 08:58

WWWow ! Swagfag amazing!.... it is working flawlessly, :superhappy:
I will study those lines of codes...impressive... I really appreciate your help. Thank you.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: JoeWinograd, yabab33299 and 136 guests