2

In my Arduino project I want to compute the SHA256 hash of a string and store the result to a string, and do this recursively many times (i.e. compute hash of hash of hash etc...). So my goal is to have areliable function as follows:

String h(String input) {...return output;}

where for example h("abc") would return "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad".

I downloaded thislibrary (from Tools->Manage libraries, it is also ingithub) and then ran the example inTestSHA256.ino which passes all the checks. However I'm stuggling to make my function work since the library doesn't have a specific example on how to compute and return a SHA256 hash.

I have been looking in function testHash_N() in TestSHA256.ino, which appears to create a hash (from struct TestHashVector data) and compare it with the precomputed hash (from struct TestHashVector hash[]).

The hash seems to be computed in lines 89-96 in TestSHA256.ino. I just want to take the actual hash string result, so for testVectorSHA256_1 in the example, I would need to have a string = "ba7816bf....15ad" as the result.

I understand that this is related to memory referencing in Arduino but I'm not experienced so I'd be grateful if you helped me with this.

EDIT: My code snippet so far is as follows, but it doesn't output the correct hash..

#include <Crypto.h>#include <SHA256.h>#include <string.h>#define HASH_SIZE 32#define BLOCK_SIZE 64char hex[256];char *hashvalue;SHA256 sha256;byte buffer[128];char *btoh(char *dest, uint8_t *src, int len) {  char *d = dest;  while( len-- ) sprintf(d, "%02x", (unsigned char)*src++), d += 2;  return dest;}char* h(Hash *hash, char* hashvalue){    size_t size = sizeof(&hashvalue);    size_t posn, len;    size_t inc = sizeof(&hashvalue);    uint8_t value[HASH_SIZE];    hash->reset();    for (posn = 0; posn < size; posn += inc) {        len = size - posn;        if (len > inc)            len = inc;        hash->update(&hashvalue + posn, len);    }    hash->finalize(value, sizeof(value));    return(btoh(hex, value, 32));}void setup(){    Serial.begin(115200);    bool tmp;    char *testvalue = "abc";    Serial.println(h(&sha256,*testvalue));}void loop(){}
askedMay 17, 2019 at 14:32
Panos's user avatar
4
  • Hint#1:sizeof(&hashvalue); is not the length of the string. It is the number of bytes of a pointer.CommentedMay 17, 2019 at 19:25
  • Hint#2:*testvaluein the statementh(&sha256,*testvalue)); is not a pointer. It is actually the value of the first character,a in thetestvalue.CommentedMay 17, 2019 at 19:27
  • Hint#3:uint8_t value[HASH_SIZE]; is a local value and cannot be returned.static uint8_t value[HASH_SIZE]; will allow that.CommentedMay 17, 2019 at 19:28
  • Thank you very much for helpingCommentedMay 18, 2019 at 2:57

2 Answers2

0

The main trick is to understand how the Arduino String class works. You can find the source code in your installation of the Arduino IDE or on github.

The basic pattern you are looking for is:

String h(String& input) {      // Pass String by reference to avoid copying  char output[OUTPUT_MAX];  char* data = input.c_str();  // Access to internal buffer  ...  return String(output);       // Return a String object of the output}

Cheers!

answeredMay 17, 2019 at 14:54
Mikael Patel's user avatar
4
  • Thanks, I've updated my question with an attempt to solve this but I'm still struggling with errors, can you please help me with the code inside to make it work?CommentedMay 17, 2019 at 15:27
  • Yes you have several issues but before going forward please acknowledge that you received an answer to your original question :) and I will get back to you.CommentedMay 17, 2019 at 17:50
  • ok right, just want to solve my problem in its entiretyCommentedMay 17, 2019 at 18:14
  • Updated my code again, it works but it doesn't output the correct hash, outputs "ffe9aaeaa2a2d5048174df0b80599ef0197ec024c4b051bc9860cff58ef7f9f3" instead of "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"CommentedMay 17, 2019 at 18:24
1

I suggest the following function. That replaces a string by its hash.It's done in place in order to save memory. Make sure the buffer yougive it is at least 65 bytes long.Warning: not tested.

#include <Crypto.h>#include <SHA256.h>#define HASH_SIZE 32SHA256 sha256;/* * Replace a string by its hash, in place. * `data' should point to a buffer at least 65 bytes in length. */hash_in_place(char *data){    uint8_t value[HASH_SIZE];    sha256.reset();    sha256.update(data, strlen(data));    sha256.finalize(value, sizeof(value));    // Convert to hex into the original buffer.    data[0] = '\0';    for (size_t i = 0; i < HASH_SIZE; i++) {        data += sprintf("%02x", value[i]);    }}
answeredMay 18, 2019 at 10:33
Edgar Bonet's user avatar
1
  • Nice implementation! Could avoidsprintf() to reduce program memory size.CommentedMay 18, 2019 at 12:22

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.