I have some data that was encrypted using the openssl (AES_*) functions. I want update this code to use the newer (EVP_*) functions. But should be able to decrypt data that was encrypted using the old code.
I've pasted below both the old and the new code. The encrypted/decrypted contents are different. i.e. I can't use them interchangeably. This means I can't upgrade the code without having to decrypt using the old code and then re-encrypt.
Are there any values for the parameters to EVP_BytesToKey so that aes_key derived is the same in both cases. Or is there any other way to accomplish the same using the (EVP_*) functions? I've tried several different values for digest, rounds and tried making iv NULL, but didn't really work i.e. it doesn't provide the same output as the old method.
The code using the AES_* functions
#include <stdio.h>
#include <openssl/aes.h>
#include <print_util.h>
static const unsigned char user_key[] = {
0x00, 0x01, 0x02, 0x03,
0x10, 0x11, 0x12, 0x13,
0x20, 0x21, 0x22, 0x23,
0x30, 0x31, 0x32, 0x33
};
int main()
{
unsigned char p_text[]="plain text";
unsigned char c_text[16];
unsigned char d_text[16];
AES_KEY aes_key;
AES_set_encrypt_key(user_key, 128, &aes_key);
AES_encrypt(p_text, c_text, &aes_key);
printf("plain text = %s\n", p_text);
printbuf((char*)c_text, 16, "cipher text = ");
AES_set_decrypt_key(user_key, 128, &aes_key);
AES_decrypt(c_text, d_text, &aes_key);
printf("plain text (decrypted) = %s \n", d_text);
return 0;
}
The code using the EVP_* functions. (Encryption code is below and the decryption code is similar).
#include <strings.h>
#include <openssl/evp.h>
#include <print_util.h>
static const unsigned char user_key[16] = {
0x00, 0x01, 0x02, 0x03,
0x10, 0x11, 0x12, 0x13,
0x20, 0x21, 0x22, 0x23,
0x30, 0x31, 0x32, 0x33
};
int main()
{
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(ctx);
const EVP_CIPHER *cipher = EVP_aes_128_ecb(); // key size 128, mode ecb
const EVP_MD *digest = EVP_md5();
int rounds = 10;
unsigned char aes_key[EVP_MAX_KEY_LENGTH];
unsigned char aes_iv[EVP_MAX_IV_LENGTH];
EVP_BytesToKey(cipher, digest, NULL, user_key, 16, rounds, aes_key, aes_iv);
EVP_EncryptInit(ctx, cipher, aes_key, aes_iv);
unsigned char p_text[]="plain text"; int p_len = sizeof(p_text);
unsigned char c_text[16]; int c_len = 16;
int t_len;
EVP_EncryptUpdate(ctx, c_text, &c_len, p_text, p_len);
EVP_EncryptFinal(ctx, (c_text + c_len), &t_len);
c_len += t_len;
printf("==> p_text: %s\n", p_text);
printbuf((char*)c_text, c_len, "==> c_text:");
}
Thanks
You don't have any key derivation in your AES_* code, so you should not use any key derivation such as EVP_BytesToKey in your new EVP_ code if you want to stay fully compatible.
And no, there is no way to make EVP_BytesToKey output the same key as above, because a cryptographic hash is used to generate the output.
Related
I have a problem with my esp8266 project. My purpose is to use esp8266 to transmit beacon frames every one second so that my android device or my laptop can receive it and display in list of APs which i can connect to.
Here is my code I wrote:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
void setup() {
delay(500);
sendBeacon("ESP8266");
ESP.deepSleep(10e5);
}
void loop() {
}
void sendBeacon(char* ssid) {
// Randomize channel //
byte channel = 1;
wifi_set_channel(channel);
uint8_t packet[128] = { 0x80, 0x00, //Frame Control
0x00, 0x00, //Duration
/*4*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address
/*10*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
/*16*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
/*22*/ 0xc0, 0x6c, //Seq-ctl
//Frame body starts here
/*24*/ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
/*32*/ 0xFF, 0x00, //Beacon interval
/*34*/ 0x01, 0x04, //Capability info
/* SSID */
/*36*/ 0x00
};
int ssidLen = strlen(ssid);
packet[37] = ssidLen;
for(int i = 0; i < ssidLen; i++) {
packet[38+i] = ssid[i];
}
uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
for(int i = 0; i < 12; i++) {
packet[38 + ssidLen + i] = postSSID[i];
}
packet[50 + ssidLen] = channel;
// get SRC MAC
unsigned char mac[6];
WiFi.macAddress(mac);
packet[10] = packet[16] = mac[0];
packet[11] = packet[17] = mac[1];
packet[12] = packet[18] = mac[2];
packet[13] = packet[19] = mac[3];
packet[14] = packet[20] = mac[4];
packet[15] = packet[21] = mac[5];
int packetSize = 51 + ssidLen;
wifi_send_pkt_freedom(packet, packetSize, 0);
delay(1);
}
I used tcpdump to capture those frame and yes, they are there. But I still couldn't see it in list of AP on my laptop and my android device.
I can see it if I stop using deep sleep mode. For example:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
void setup() {
delay(500);
// sendBeacon("ESP8266");
// ESP.deepSleep(10e5);
}
void loop() {
sendBeacon("ESP8266");
}
void sendBeacon(char* ssid) {
// Randomize channel //
byte channel = 1;
wifi_set_channel(channel);
uint8_t packet[128] = { 0x80, 0x00, //Frame Control
0x00, 0x00, //Duration
/*4*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address
/*10*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
/*16*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
/*22*/ 0xc0, 0x6c, //Seq-ctl
//Frame body starts here
/*24*/ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
/*32*/ 0xFF, 0x00, //Beacon interval
/*34*/ 0x01, 0x04, //Capability info
/* SSID */
/*36*/ 0x00
};
int ssidLen = strlen(ssid);
packet[37] = ssidLen;
for(int i = 0; i < ssidLen; i++) {
packet[38+i] = ssid[i];
}
uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
for(int i = 0; i < 12; i++) {
packet[38 + ssidLen + i] = postSSID[i];
}
packet[50 + ssidLen] = channel;
// get SRC MAC
unsigned char mac[6];
WiFi.macAddress(mac);
packet[10] = packet[16] = mac[0];
packet[11] = packet[17] = mac[1];
packet[12] = packet[18] = mac[2];
packet[13] = packet[19] = mac[3];
packet[14] = packet[20] = mac[4];
packet[15] = packet[21] = mac[5];
int packetSize = 51 + ssidLen;
wifi_send_pkt_freedom(packet, packetSize, 0);
delay(1);
}
Does anyone know why? Please help me to get this, thanks!
First of all, ESP.deepSleep(10e5) makes the processor sleep for 100ms, not a second. The correct would be ESP.deepSleep(10e6). Secondly, you are trying to send just one packet every second or so, it's quite hard to make sure that the wifi reading from the device is gonna get that packet for sure and display it on the list of SSIDs. From my experiments, I had to send three packets every 200ms to make sure it was displayed on my android mobile and pc. You can try to play with the number of packets you send and the interval to see what fits you best...
Also, make sure to configure the ESP correctly at the setup function. When I tried my similar code I had to use two instructions: wifi_set_opmode(STATION_MODE) and wifi_promiscuous_enable(1)
Could you pls help me in this type of task.Actually I dont understand what I should provide as an answer
A given bit vector has length n. It is known that the vector can contain only two ones. A combinational system needs to calculate the distance between the ones. For example, in vector "10100" the distance is 2. Give the high-level specification.
When google turned up this SO question for me, I was pretty excited. I was hoping there'd be some code here I could repurpose. Alas, the OP's question was too abstract for a concrete solution to get proposed.
Still, for the next guy, here's at least /a/ solution, designed for MSVC x64:
#include <intrin.h> // __lzcnt64 & _BitScanForward64
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
/// <summary>
/// Given a pointer to an array of bits, prints out the distance between the bits.
/// </summary>
/// <param name="pBits">Pointer to the bits</param>
/// <param name="len">Length of the array in bytes</param>
/// <param name="carry">Previous value of carry</param>
/// <returns>Final carry</returns>
/// <remarks>Reading right to left, a bit pattern of 11100101 (aka 0xE5) will print 1, 2, 3, 1, 1</remarks>
uint64_t CountBitDistance(const uint8_t* pBits, const size_t len, uint64_t carry = 0)
{
// Assumes len divides evenly by 8. Depending on the platform,
// pBits might also need to be 8 byte aligned. Left as an exercise.
assert((len % 8) == 0);
const uint64_t* pUll = (const uint64_t*)pBits;
for (size_t x = 0; x < len / 8; pUll++, x++)
{
uint64_t ull = *pUll;
// Grab the value before we start modifying ull
const uint64_t newcarry = __lzcnt64(ull);
unsigned long res = 0;
// Returns false when ull is zero. res is zero based.
while (_BitScanForward64(&res, ull))
{
// Tempting though it might be, you can't just increment res and
// do both shifts at once. If the only bit set is the most
// significant one, adding 1 gives you 64. Shifting a 64bit value
// by 64 is undefined behavior in C. On x64 for example, it does
// nothing. If you are *sure* that res will never be 63, or if
// you are on a platform that handles shifts > 63 differently (and
// don't need a portable solution), you could combine them and
// increase perf (by a tiny amount).
// So, first get rid of the zeros...
ull >>= res;
// ... then turn off the bit we just found.
ull >>= 1;
// If we found a bit at position 0, we want to report 1.
res++;
// And apply any carry in from the previous ull.
const uint64_t d = carry + res;
// Carry in applied.
carry = 0;
printf("%llu\n", d);
}
// Remember that we might not go into the loop above at all, so carry
// won't necessarily be zero.
carry += newcarry;
}
// Useful if the source of our bits is continuing to produce data. We may
// need the final value from the previous batch to apply to the next.
return carry;
}
int main()
{
constexpr const uint8_t bits[] = {
0xAA, 0x25, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xAA, 0x25, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
};
constexpr const uint8_t bits2[] = { 0x2, 0, 0, 0, 0, 0, 0, 0 };
uint64_t t1 = CountBitDistance(bits, sizeof(bits));
printf("t1: %llu\n\n", t1);
uint64_t t2 = CountBitDistance(bits2, sizeof(bits2), t1);
printf("t2: %llu\n", t2);
}
No doubt someone else will pop up with a drastically better solution using some clever bit twiddling hacks. Still, at least now there's something.
Using webduino library, the Web_HelloWorld example has the following:
// CHANGE THIS TO YOUR OWN UNIQUE VALUE
static uint8_t mac[6] = { 0x02, 0xAA, 0xBB, 0xCC, 0x00, 0x22 };
What's with the 0x02 etc? If my mac address is 90-A2-DA... do I simply change the line of code to be...
static uint8_t mac[6] = { 90, A2, DA, ... };
? Or do I need to keep the format of the x's? Thanks!
You should keep the "0x" prefix, which specifies the value to be hexadecimal. For example, if you just gave it "90", it would assume a decimal, base-10 90 instead of a hexadecimal 90.
static uint8_t mac[6] = { 0x90, 0xA2, 0xDA, ... };
I am working on a project, and I am trying to get a grasp of it. Using the WiShield. I have been trying to complete the example program for a simple tweeter. However, I have had no luck yet. I have been trying to find the solutions, and everything I find never seems to work. How do I fix this problem?
My code is below as well as the errors I receive.
Code
#include <WiServer.h>
#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2
unsigned char local_ip[] = {192,168,2,2};
unsigned char gateway_ip[] = {192,168,2,1};
unsigned char subnet_mask[] = {255,255,255,0};
const prog_char ssid[] PROGMEM = {"myssid"};
unsigned char security_type = 3; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
const prog_char security_passphrase[] PROGMEM = {"mywifipassword"};
prog_uchar wep_keys[] PROGMEM = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3
};
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// Authentication string for the Twitter account.
char* auth = "[user:pass]"; // Base64 encoded USERNAME:PASSWORD
// This function generates a message with the current system time.
void currentTime() {
WiServer.print("Arduino has been running for ");
WiServer.printTime(millis());
}
// A request that sends a tweet using the currentTime function.
TWEETrequest sentMyTweet(auth, currentTime);
void setup() {
// Initialize WiServer (we'll pass NULL for the page serving function since we don't need to serve web pages).
WiServer.init(NULL);
// Enable Serial output and ask WiServer to generate log messages (optional).
Serial.begin(57600);
WiServer.enableVerboseMode(true);
}
// Time (in milliseconds) when the next tweet should be sent.
long tweetTime = 0;
void loop(){
// Check if it's time to sent a tweet
if (millis() >= tweetTime) {
sentMyTweet.submit();
// Send next tweet 5 minutes from now
tweetTime += 1000 * 60 * 5;
}
// Run WiServer
WiServer.server_task();
delay(10);
}
Errors
In file included from SimpleTweeter.cpp:5:
C:\Program Files (x86)\arduino-1.0\libraries\WiShield/WiServer.h:198: error: conflicting return type specified for 'virtual void Server::write(uint8_t)'
C:\Program Files (x86)\arduino-1.0\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
SimpleTweeter.pde:-1: error: 'TWEETrequest' does not name a type
SimpleTweeter.cpp: In function 'void loop()':
SimpleTweeter.pde:-1: error: 'sentMyTweet' was not declared in this scope
(I am new to Arduino.)
It looks like the WiServer library hasn't been upgraded to work with Arduino 1.0. In this version of the Arduino software, the return type of the write method in the Print class was changed from void to size_t.
There is a fork of WiShield on GitHub by Juan C. Muller which makes it compatible with Arduino 1.0.
The subsequent error about the type TWEETrequest is a knock-on effect of this previous error.
Is there any way to calculate the largest outcome from an Rijndael encryption with a fixed array length?
Encryption method: RijndaelManaged
Padding: PKCS7
CipherMode: CBC
BlockSize 128
KeySize: 128
I need this as im converting a database where all string are going to be encrypted so i need to change the size of all string fields.
Everything you need to try this out:
public partial class Form1 : Form
{
private SymmetricAlgorithm mEncryptionType;
public Form1()
{
mEncryptionType = new RijndaelManaged();
mEncryptionType.Padding = PaddingMode.PKCS7; //PaddingMode.None;
mEncryptionType.Mode = CipherMode.CBC;
mEncryptionType.BlockSize = 128; // 192; // 256; // Update byte array to IV when changed
mEncryptionType.KeySize = 128; // 192; // 256; // Update byte array to Key when changed
mEncryptionType.IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
mEncryptionType.Key = new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
int encrypted_size = CalculateEncryptedSize(new byte[] { 0x22, 0x23, 0x44 });
// Shows Theran's point about exact block size
encrypted_size = CalculateEncryptedSize(new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF });
}
/// <summary>
/// Calculate the encrypted size of input buffer
/// </summary>
/// <param name="inputBuffer">The input buffer</param>
/// <returns>Size of the encrypted buffer</returns>
public int CalculateEncryptedSize(byte[] inputBuffer)
{
int extra_padding = 0;
if (mEncryptionType.Padding != PaddingMode.None)
{
int padding_size = (mEncryptionType.BlockSize / 8);
extra_padding = (padding_size - (inputBuffer.Length % padding_size));
}
return inputBuffer.Length + extra_padding;
}
}
Yes. Round up your input size to the nearest multiple of your block size (e.g. 128 / 8 = 16 bytes).
extraBytesNeeded = (16 - (inputSize % 16)) % 16;
maxSize = inputSize + extraBytesNeeded.
Jeff's answer is almost correct, except that PKCS7 will always add padding to the message, even if the message exactly fits inside an integral number of blocks. Also, don't forget that if using a random IV that the IV has to be stored too. The corrected formula for the length of a PKCS7 padded message is:
extraBytesNeeded = (16 - (inputSize % 16)); // whole block of padding if input fits exactly
maxSize = inputSize + extraBytesNeeded + IVbytes;