CryptEncrypt fails on pocketpc

A

Anatoly

I am testing out some encryption on pocket pc with C#.net, (see below code)
it executes through Generating the key, but fails when trying to actually
encrypt data with it.

Does anyone know what I am doing wrong?


imports are:
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Diagnostics;
using System.Data;
using System.Runtime.InteropServices ;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.IO;
using System.Threading;


my encryption test method is:

public byte[] Encrypt(byte[] data)
{
int lasterror = 0;
// contains encrypted data
byte[] buffer = null;
IntPtr hProv = IntPtr.Zero;
IntPtr hKey = IntPtr.Zero;
uint bufLength = (uint)data.Length;
uint dataLength = (uint)data.Length;
if (!WinApi.CryptAcquireContext(ref hProv, null, WinApi.MS_DEF_PROV,
WinApi.PROV_RSA_FULL,
WinApi.CRYPT_VERIFYCONTEXT))
{
lasterror = Marshal.GetLastWin32Error();
Error(1, lasterror);
return null;
}

if (!WinApi.CryptGenKey(hProv, WinApi.CALG_RC2 ,
WinApi.CRYPT_EXPORTABLE, ref hKey))
{
lasterror = Marshal.GetLastWin32Error();
Error(3, lasterror);
return null;
}

// below call fails and lasterror also retrieved as 0. no informatio on
why.
if (!WinApi.CryptEncrypt(hKey, IntPtr.Zero, true, 0, null, ref
dataLength, bufLength))
{
lasterror = Marshal.GetLastWin32Error();
Error(10, lasterror);
}

buffer = new byte[dataLength];
Buffer.BlockCopy(data, 0, buffer, 0, data.Length);
dataLength = (uint)data.Length;
bufLength = (uint)buffer.Length;

if (!WinApi.CryptEncrypt(hKey, IntPtr.Zero, true, 0, buffer, ref
dataLength, bufLength))
{
lasterror = Marshal.GetLastWin32Error();
Error(11, lasterror);
}
}



The WinApi class is defined as follows:

class WinApi
{

public const string MS_DEF_PROV = "Microsoft Base Cryptographic
Provider v1.0";
public const string MS_ENHANCED_PROV = "Microsoft Enhanced
Cryptographic Provider 1.0";
public const string MS_DEF_RSA_SIG_PROV= "Microsoft RSA Signature
Cryptographic Provider";
public const uint PROV_RSA_FULL = 1;
public const uint PROV_RSA_SIG = 2;
public const uint PROV_DSS = 3;

public const uint AT_SIGNATURE = 2;
//public static readonly uint CALG_RSA_KEYX = 41984;
public const uint ALG_CLASS_SIGNATURE = (1 << 13);
public const uint ALG_TYPE_RSA = (2 << 9);
public const uint ALG_SID_RSA_ANY = 0;
public const uint ALG_CLASS_KEY_EXCHANGE = (5 << 13);
public const uint ALG_CLASS_HASH = (4 << 13);
public const uint ALG_SID_MD5 = 3;
public const uint ALG_TYPE_DSS = (1 << 9) ;
public const uint ALG_TYPE_ANY = 0;
public const uint ALG_SID_DSS_ANY = 0;
public const uint ALG_CLASS_DATA_ENCRYPT = (3 << 13);
public const uint ALG_TYPE_BLOCK = (3 << 9);
public const uint ALG_TYPE_STREAM = (4 << 9);
public const uint ALG_SID_DES = 1;
public const uint ALG_SID_RC4 = 1;
public const uint ALG_SID_RC2 = 2;


public const uint CALG_RC2 =
(ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_RC2);
public const uint CALG_RC4 =
(ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_STREAM|ALG_SID_RC4);

public const uint CALG_RSA_SIGN = (ALG_CLASS_SIGNATURE |
ALG_TYPE_RSA | ALG_SID_RSA_ANY);
public const uint CALG_RSA_KEYX =
(ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_RSA|ALG_SID_RSA_ANY);
public const uint CALG_DSS_SIGN = (ALG_CLASS_SIGNATURE |
ALG_TYPE_DSS | ALG_SID_DSS_ANY);
public const uint CALG_MD5 = (ALG_CLASS_HASH |
ALG_TYPE_ANY | ALG_SID_MD5);
public const uint CALG_DES =
(ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_DES);
public const uint CRYPT_VERIFYCONTEXT = 0xf0000000;
public const uint CRYPT_EXPORTABLE = 0x00000001;
const string CryptDll = "coredll.dll";

[DllImport(CryptDll)]
public static extern bool CryptAcquireContext(ref IntPtr phProv,
string
pszContainer, string pszProvider,uint dwProvType, uint dwFlags);

[DllImport(CryptDll)]
public static extern bool CryptGenKey(IntPtr hProv, uint Algid, uint
dwFlags, ref IntPtr phKey);

[DllImport(CryptDll)]
public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash,
bool Final, uint dwFlags, byte[] pbData,
ref uint pdwDataLen, uint dwBufLen);

[DllImport(CryptDll)]
public static extern bool CryptDestroyKey(IntPtr hKey);


[DllImport(CryptDll)]
public static extern bool CryptReleaseContext(
IntPtr hProv, uint dwFlags);

}
 
P

Pieter Philippaerts

Anatoly said:
I am testing out some encryption on pocket pc with C#.net, (see below code)
it executes through Generating the key, but fails when trying to actually
encrypt data with it.

Your definition of CryptEncrypt is wrong. Try this:

[DllImport(CryptDll)]
public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, int Final,
uint dwFlags, byte[] pbData, ref uint pdwDataLen, uint dwBufLen);

There's a difference between 'bool' and 'BOOL' in C. Like in C#, bool is a
1-byte variable and BOOL is a 4-byte variable. The CryptEncrypt uses the
4-byte type and you declared it as a 1-byte type. This corrupts the
parameters on the stack, and hence the error.

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl
 
A

Anatoly

Pieter,

I replaced the signature as you suggested, and provided value of 1 instead
of "True"
The CALG_RC4 encryption call worked!!,
but when I replace the CALG_RC4 with CALG_RSA_KEYX or CALG_RSA_SIGN, the
encryption fails,
isn't this encryption also supported on pocket pc?

-Anatoly

Pieter Philippaerts said:
Anatoly said:
I am testing out some encryption on pocket pc with C#.net, (see below code)
it executes through Generating the key, but fails when trying to actually
encrypt data with it.

Your definition of CryptEncrypt is wrong. Try this:

[DllImport(CryptDll)]
public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, int Final,
uint dwFlags, byte[] pbData, ref uint pdwDataLen, uint dwBufLen);

There's a difference between 'bool' and 'BOOL' in C. Like in C#, bool is a
1-byte variable and BOOL is a 4-byte variable. The CryptEncrypt uses the
4-byte type and you declared it as a 1-byte type. This corrupts the
parameters on the stack, and hence the error.

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top