I don't why I cannot make a AES encryption using the code below.
let key="12345678900987654321564738290123".bytes;//32
let iv="passwordpasswordwordpasswordpass".bytes;//32
let message="Hello text fcrypt Hello text for enfor r encryptg ";
print(message.count) //50
let data = Padding.pkcs7.add(to: message.bytes, blockSize: AES.blockSize)
do {
let aes = try AES(key: key, blockMode: .CBC(iv: iv), padding: .pkcs7)
let ciphertext = try aes.encrypt(data)
print(ciphertext)
} catch {
print(error)//dataPaddingRequired
}
Your IV should be 16 bytes, not 32. AES always has a block size of 128 bits, which divided by 8 is of course 16 bytes. CBC mode uses an IV of the same size as the block size as most (but not all) modes of encryption do.
The authenticated GCM mode is a bit of an odd one out: it uses a nonce / IV of 12 bytes by default and is only available for ciphers with a block size of 128 bits.
Related
I have set an 8-bit bus on (PD0:PD7) on the stm32 MCU to send addresses to another chip (0:255). I am interested if a function like below would work for fast change in addresses. I could not find an example directly showing register to be equal to integer so I want to confirm it would work. I need a function to which I will give an integer value for the address (0:255) and it will set the 8 pins of the bus with this value:
void chipbus(uint16_t bus8){
GPIOD->regs->BSRR = bus8; // set all the '1' in bus8 to high
GPIOD->regs->BRR = 255-bus8; // 255-bus8 inverts the 8 bits
// BRR to set the new '1' to low
}
If this solution works, I am curious also if I change the bus to ports PD5:PD12 would my function work as:
void chipbus(uint16_t bus8){
GPIOD->regs->BSRR = bus8*32; // set all '1' in bus8 to high
// multiply by 32 to shift 5 bits/pins
GPIOD->regs->BRR = (255-bus8)*32; // 255-bus8 inverts the 8 bits
// BRR to set the new '1' to low
}
Thank you!
Yes, both should work. However, a more recognisable but equivalent formulation would be:
void chipbus(uint16_t bus8) {
GPIOD->regs->BSRR = bus8; // set all the '1' in bus8 to high
GPIOD->regs->BRR = (~bus8) & 0xFF; // inverts the 8 bits // BRR to set the new '1' to low
}
void chipbus(uint16_t bus8) {
GPIOD->regs->BSRR = bus8<<5; // set all '1' in bus8 to high, shift 5 bits
GPIOD->regs->BRR = ((~bus8)&0xFF)<<5; // inverts the 8 bits
}
But, there is an even faster way. BSRR is a 32bit register than can both set and reset. You can combine the two write accesses into one:
void chipbus(uint16_t bus8) {
GPIOD->regs->BSRR =
(bus8<<5) | (((~bus8) & 0xFF) << (16+5));
}
Happy bit-fiddling!
Yes, it'd definitely work. However, as others have noted, it's advisable to set the outputs in a single operation.
Taking advantage of the full 32 bit BSRR register, it can be done without inverting the data bits:
GPIOD->regs->BSRR = bus8 | (0xFF << 16);
or
GPIOD->regs->BSRR = (bus8 << 5) | (0xFF << (16 + 5));
because BSRR has the functionality to set some bits and reset some others in a single write operation, and when both the set and reset bits for a particular pin is set, the output becomes 1.
I wouldn't recommend using this approach. Writing to BSRR and BRR as two separate steps means that the bus will transition through an unintended state where some bits are still set from the previous value.
Instead, consider writing directly to the GPIO output data register (ODR). If you need to preserve the original value of the upper bits in the port, you can do that on the CPU side:
GPIOD->regs->ODR = (GPIOD->regs->ODR & 0xff00) | (bus8 & 0x00ff);
I'm try to read SDHC card with SPI and a DSP.
I succeed to read a lot of information (capacity, some other informations) using CMD17 command.
Now I want to use CMD18 command (READ_MULTIPLE_BLOCK), because I want to read 2 sectors (2 * 512 bytes). I put all the values in a buffer.
When I read it, there are 4 bytes (when I'm using a 4GB Class 4 or 10 bytes when I'm using a 4GB Class 10) between the 2 sectors which are not on the card (I read the 2 sectors with HxD software). What are these values?
This is an example with a 4GB Class 4:
Buffer values :
buffer[511] = 68 **// Good value**
buffer[512] = 143 // Bad value
buffer[513] = 178 // Bad value
buffer[514] = 255 // Bad value
buffer[515] = 254 // Bad value
buffer[516] = 48 **// Good value**
Real values readed with HxD
buffer[511] = 68 **// Good value**
buffer[512] = 48 **// Good value**
buffer[513] = 54 **// Good value**
buffer[514] = 48 **// Good value**
buffer[515] = 52 **// Good value**
buffer[516] = 69 **// Good value**
I don't send CRC (0xFF), does the problem from that?
Thank you for your help.
Regards,
buffer[512] = 143 // Bad value
buffer[513] = 178 // Bad value
These two bytes are CRC for 512-byte block. Can be not used, but can not be rejected from received stream.
buffer[514] = 255 // Bad value
Card pre-charge next block, you will get random quantity (include zero) of 255's each time. (Depends of SPI speed and card speed)
buffer[515] = 254 // Bad value
Card is ready to stream next data block. You should awaiting for 254, then you know the following data will be correct. In fact, even before first block of data, you should also wait/get these 255...255, 254.
I've been experimenting with writing to an external EEPROM using SPI and I've had mixed success. The data does get shifted out but in an opposite manner. The EEPROM requires a start bit and then an opcode which is essentially a 2-bit code for read, write and erase. Essentially the start bit and the opcode are combined into one byte. I'm creating a 32-bit unsigned int and then bit-shifting the values into it. When I transmit these I see that the actual data is being seen first and then the SB+opcode and then the memory address. How do I reverse this to see the opcode first then the memory address and then the actual data. As seen in the image below, the data is BCDE, SB+opcode is 07 and the memory address is 3F. The correct sequence should be 07, 3F and then BCDE (I think!).
Here is the code:
uint8_t mem_addr = 0x3F;
uint16_t data = 0xBCDE;
uint32_t write_package = (ERASE << 24 | mem_addr << 16 | data);
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_SPI_Transmit(&hspi1, &write_package, 2, HAL_MAX_DELAY);
HAL_Delay(10);
}
/* USER CODE END 3 */
It looks like as your SPI interface is set up to process 16 bit halfwords at a time. Therefore it would make sense to break up the data to be sent into 16 bit halfwords too. That would take care of the ordering.
uint8_t mem_addr = 0x3F;
uint16_t data = 0xBCDE;
uint16_t write_package[2] = {
(ERASE << 8) | mem_addr,
data
};
HAL_SPI_Transmit(&hspi1, (uint8_t *)write_package, 2, HAL_MAX_DELAY);
EDIT
Added an explicit cast. As noted in the comments, without the explicit cast it wouldn't compile as C++ code, and cause some warnings as C code.
You're packing your information into a 32 bit integer, on line 3 of your code you have the decision about which bits of data are placed where in the word. To change the order you can replace the line with:
uint32_t write_package = ((data << 16) | (mem_addr << 8) | (ERASE));
That is shifting data 16 bits left into the most significant 16 bits of the word, shifting mem_addr up by 8 bits and or-ing it in, and then adding ERASE in the least significant bits.
Your problem is the Endianness.
By default the STM32 uses little edian so the lowest byte of the uint32_t is stored at the first adrress.
If I'm right this is the declaration if the transmit function you are using:
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
It requires a pointer to uint8_t as data (and not a uint32_t) so you should get at least a warning if you compile your code.
If you want to write code that is independent of the used endianess, you should store your data into an array instead of one "big" variable.
uint8_t write_package[4];
write_package[0] = ERASE;
write_package[1] = mem_addr;
write_package[2] = (data >> 8) & 0xFF;
write_package[3] = (data & 0xFF);
I am having problem setting the parameters for the AES GCM mechanism.
I am receving the following error
#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL
What am I doing wrong?
CK_BYTE iv[12] = { 0 };
CK_MECHANISM mechanismAES = { CKM_AES_GCM, NULL_PTR, 0 };
CK_GCM_PARAMS params = {
.pIv=iv,
.ulIvLen=12,
.ulIvBits=96,
.pAAD=NULL,
.ulAADLen=0,
.ulTagBits=0
};
mechanismAES.pParameter = ¶ms;
mechanismAES.ulParameterLen = sizeof(params);
C_EncryptInit(hSession, &mechanismAES, hKey);
.ulTagBits=0 is very likely the issue. The tag size is the size of the authentication tag. You would not have an authenticated mode of encryption if you left it out.
Valid tag sizes of GCM are 128, 120, 112, 104 or 96 bits. Smaller tag sizes such as 64 bits may be acceptable by some API's. You are however strongly encouraged to keep to the 128 bit tag size, as the security of GCM strongly depends on it.
You may also want to specify either the IV len or the IV bits if the error doesn't go away.
I need to establish a secure communication between a PC and a device which supports RSA encryption and signature with SHA1. As I have already used Crypto++ in other parts of my application, I would like to utilize Crypto++ for this as well.
The device is very primitive but allows executing a program I write on it. It has raw RSA and SHAa functions built-in; However, it has very little memory to work with, 2K bytes to be precise.
I have to encrypt and sign a message from a PC. Then the device decrypts and verifies the message. The device will then reply an encrypted message and sign on it. The PC will decrypt the message and verify it afterwards. I have implemented the raw RSA encryption, signature and verification with SHA1 inside the device using the built-in functions. The messages is short enough to be done in a single round.
However, I don't know how to encrypt a message with raw RSA using Crypto++ without involving OAEP or PKCS#1. Could somebody kind enough to show me some sample code? Thanks a ton!
I don't know how to encrypt a message with raw RSA using Crypto++ without
involving OAEP or PKCS#1. Could somebody kind enough to show me some sample code?
That's easy enough when you know where to look: Raw RSA from the Crypto++ wiki. The code below was taken from the page.
Encryption
Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9");
RSA::PublicKey pubKey;
pubKey.Initialize(n, e);
///////////////////////////////////////////////////////////////
Integer m, c;
string message = "secret";
cout << "message: " << message << endl;
// Treat the message as a big endian byte array
m = Integer((const byte *)message.data(), message.size());
cout << "m: " << hex << m << endl;
// Encrypt
c = pubKey.ApplyFunction(m);
cout << "c: " << hex << c << endl;
Decryption
Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9");
AutoSeededRandomPool prng;
RSA::PrivateKey privKey;
privKey.Initialize(n, e, d);
///////////////////////////////////////////////////////////////
Integer c("0x3f47c32e8e17e291"), r;
string recovered;
// Decrypt
r = privKey.CalculateInverse(prng, c);
cout << "r: " << hex << r << endl;
// Round trip the message
size_t req = r.MinEncodedSize();
recovered.resize(req);
r.Encode((byte *)recovered.data(), recovered.size());
cout << "recovered: " << recovered << endl;
Here's a sample output:
$ ./cryptopp-raw-rsa.exe
message: secret
m: 736563726574h
c: 3f47c32e8e17e291h
r: 736563726574h
recovered: secret
There is one caveat: c = m ^ e mod n, so there are some limits on plaint text size and cipher text size. Essentially, m and c must be smaller than n. In this example, replacing the string secret with now is the time for all good men to come to the aid of their country would fail because it's larger than n when converted to an Integer.
You can get the maximum plain text size with the function MaxPreImage(), and the maximum cipher text size with MaxImage().
I have to encrypt and sign a message from a PC. Then the device decrypts
and verifies the message. The device will then reply an encrypted message
and sign on it. The PC will decrypt the message and verify it afterwards.
On the surface, this looks like it will suffer replay attacks. You might need a protocol with the protection.
Here is a demo function I wrote when I first did RSA encryption and decryption with Crypto++. I wrote it just to understand the basics. I hope it helps:
#include <cryptopp/files.h>
#include <cryptopp/modes.h>
#include <cryptopp/osrng.h>
#include <cryptopp/rsa.h>
#include <cryptopp/sha.h>
using namespace CryptoPP;
void rsa_examples()
{
// Keys created here may be used by OpenSSL.
//
// openssl pkcs8 -in key.der -inform DER -out key.pem -nocrypt
// openssl rsa -in key.pem -check
AutoSeededRandomPool rng;
// Create a private RSA key and write it to a file using DER.
RSAES_OAEP_SHA_Decryptor priv( rng, 4096 );
TransparentFilter privFile( new FileSink("rsakey.der") );
priv.DEREncode( privFile );
privFile.MessageEnd();
// Create a private RSA key and write it to a string using DER (also write to a file to check it with OpenSSL).
std::string the_key;
RSAES_OAEP_SHA_Decryptor pri( rng, 2048 );
TransparentFilter privSink( new StringSink(the_key) );
pri.DEREncode( privSink );
privSink.MessageEnd();
std::ofstream file ( "key.der", std::ios::out | std::ios::binary );
file.write( the_key.data(), the_key.size() );
file.close();
// Example Encryption & Decryption
InvertibleRSAFunction params;
params.GenerateRandomWithKeySize( rng, 1536 );
std::string plain = "RSA Encryption", cipher, decrypted_data;
RSA::PrivateKey privateKey( params );
RSA::PublicKey publicKey( params );
RSAES_OAEP_SHA_Encryptor e( publicKey );
StringSource( plain, true, new PK_EncryptorFilter( rng, e, new StringSink( cipher )));
RSAES_OAEP_SHA_Decryptor d( privateKey );
StringSource( cipher, true, new PK_DecryptorFilter( rng, d, new StringSink( decrypted_keydata )));
assert( plain == decrypted_data );
}