padding zeros in char *

S

s.seitz

hi gods and programmers!

i've got a weird problem with strlen() in C.

in a current project, i need to AES_decrypt() some string. By now, i'm
using the libssl (openssl) API.

To get this AES_decrypt() work, i needed to split the encoded input
into pieces of 16 byte. This works as expected.

Only problem is every LAST piece in a line, which is propably shorter
than 16 byte (as you already assumed, this differs between 1 and 15).
According to the manual, i'll need to pad the piece with zeros until it
reaches the length of 16 byte.

Well, this is my problem: I can't pad with \0 since C cuts this
'string' at the first occurency of \0.

I tried almost everything: strcat, membcpy, writing directly to the
address ... nothing... the last piece of encoded data stays as short as
before my trials.



Again, my problem is NOT the AES_decrypt(). My problem is padding the
input with trailing \0 bytes.




void AES_decrypt(const unsigned char *in, unsigned char *out,
^^^^ const AES_KEY
*key);
this needs to be strlen()=16 ---------'





Please, if someone knows an answer, let me know.

Thanks in advance.

Stephan Seitz
<[email protected]>
 
E

Emmanuel Delahaye

(e-mail address removed) a écrit :
I tried almost everything: strcat, membcpy, writing directly to the
address ... nothing... the last piece of encoded data stays as short as
before my trials.

It might a job for strncpy(). Read the manual carefully.
 
M

Michael Mair

[snipped some white space]
hi gods and programmers!

i've got a weird problem with strlen() in C.

in a current project, i need to AES_decrypt() some string. By now, i'm
using the libssl (openssl) API.

To get this AES_decrypt() work, i needed to split the encoded input
into pieces of 16 byte. This works as expected.

Only problem is every LAST piece in a line, which is propably shorter
than 16 byte (as you already assumed, this differs between 1 and 15).
According to the manual, i'll need to pad the piece with zeros until it
reaches the length of 16 byte.

Well, this is my problem: I can't pad with \0 since C cuts this
'string' at the first occurency of \0.

I tried almost everything: strcat, membcpy, writing directly to the
address ... nothing... the last piece of encoded data stays as short as
before my trials.

Again, my problem is NOT the AES_decrypt(). My problem is padding the
input with trailing \0 bytes.

void AES_decrypt(const unsigned char *in, unsigned char *out,
^^^^ const AES_KEY
*key);
this needs to be strlen()=16 ---------'


Please, if someone knows an answer, let me know.

strlen() is not the right tool to measure an array length
as it will stop at the first zero/'\0' byte. Regardless how
many more follow.
Your spec probably only demanded an array of unsigned char.
So there is nothing to worry about in this case. Pad your
last "string" with '\0' as needed and you will be fine.
The padding will not be visible to strlen() and you can
only inspect the zero values by printing them out as integer
values.


Cheers
Michael
 
M

Martin Ambuhl

hi gods and programmers!

i've got a weird problem with strlen() in C.

in a current project, i need to AES_decrypt() some string. By now, i'm
using the libssl (openssl) API.

To get this AES_decrypt() work, i needed to split the encoded input
into pieces of 16 byte. This works as expected.

Only problem is every LAST piece in a line, which is propably shorter
than 16 byte (as you already assumed, this differs between 1 and 15).
According to the manual, i'll need to pad the piece with zeros until it
reaches the length of 16 byte.

Well, this is my problem: I can't pad with \0 since C cuts this
'string' at the first occurency of \0.

I tried almost everything: strcat, membcpy, writing directly to the
address ... nothing... the last piece of encoded data stays as short as
before my trials.

If AES_decrypt expects an array of 16 chars, possibly zero-padded on the
right, there is nothing to stand in your way. Strings have nothing to
do with it. There are many ways to do this. Here is a pedestrian one:
#include <stdio.h>
#include <ctype.h>

#define AESsize 16

void pseudo_AES_decrypt(char *s)
{
int i;
printf("Received array: ");
for (i = 0; i < AESsize; i++) {
if (isprint(s))
putchar(s);
else
printf("\\%03o", (unsigned) s);
}
putchar('\n');
}


int main(void)
{
char *tst = "abcedefghijklmnopqrstuvwxyz"
"ABCDEFGHHIJKLMNOPQRSTUVWXYZ";
char buf[AESsize], *t, *b;
int i;
for (t = tst; *t;) {
for (i = 0; b = buf, i < AESsize; i++)
b = (*t) ? *t++ : *t;
pseudo_AES_decrypt(buf);
}
return 0;
}

Received array: abcedefghijklmno
Received array: pqrstuvwxyzABCDE
Received array: FGHHIJKLMNOPQRST
Received array: UVWXYZ\000\000\000\000\000\000\000\000\000\000
 
S

s.seitz

Many thank's to all of you, guys!

Your answers were really helpful.

Finally, the strncpy() manual solved my problem.

char *strncpy(char *dest, const char *src, size_t n);

--> "In the case where the length of src is less than that of n, the
remainder of dest will be padded with nulls."

This isn't that speedy than you solution, martin, so i'll swap over to
your code.

Many thanks again!

Greetings

Stephan Seitz
<[email protected]>
 
M

Mark McIntyre

hi gods and programmers!

i've got a weird problem with strlen() in C.

(of trying to use the str... functions on things which aren't strings)

Your problem is that you're thinking of your 16-byte chunks as
strings. They're not - they can't be, since they contain embedded
nulls. Treat them as blocks of memory,. and use the mem... functions
maybe?
 
S

SM Ryan

(e-mail address removed) wrote:
# hi gods and programmers!
#
# i've got a weird problem with strlen() in C.
#
# in a current project, i need to AES_decrypt() some string. By now, i'm
# using the libssl (openssl) API.
#
# To get this AES_decrypt() work, i needed to split the encoded input
# into pieces of 16 byte. This works as expected.
#
# Only problem is every LAST piece in a line, which is propably shorter
# than 16 byte (as you already assumed, this differs between 1 and 15).
# According to the manual, i'll need to pad the piece with zeros until it
# reaches the length of 16 byte.
#
# Well, this is my problem: I can't pad with \0 since C cuts this
# 'string' at the first occurency of \0.

length := strlen(string)
while length>0,
memset(destination,16,0)
if length>16,
piecelength := 16
else
piecelength := length
memcpy(destination,string,piecelength)
decrypt(destination)
string +:= piecelength
length -:= piecelength
 
J

Joe Wright

hi gods and programmers!

i've got a weird problem with strlen() in C.

in a current project, i need to AES_decrypt() some string. By now, i'm
using the libssl (openssl) API.

To get this AES_decrypt() work, i needed to split the encoded input
into pieces of 16 byte. This works as expected.

Only problem is every LAST piece in a line, which is propably shorter
than 16 byte (as you already assumed, this differs between 1 and 15).
According to the manual, i'll need to pad the piece with zeros until it
reaches the length of 16 byte.

Well, this is my problem: I can't pad with \0 since C cuts this
'string' at the first occurency of \0.

I tried almost everything: strcat, membcpy, writing directly to the
address ... nothing... the last piece of encoded data stays as short as
before my trials.



Again, my problem is NOT the AES_decrypt(). My problem is padding the
input with trailing \0 bytes.

How about '0' bytes instead of '\0' bytes?
 
K

Keith Thompson

Martin Ambuhl said:
Joe said:
(e-mail address removed) wrote:
How about '0' bytes instead of '\0' bytes?

What earthly difference could that make?
[Ans: none.]

Presumably the difference is that padding with '0' bytes won't work.
According to the OP, the AES_decrypt requires the last block to be
padded with '\0' bytes.

Joe, what did you have in mind?
 
M

Martin Ambuhl

Keith said:
Martin Ambuhl said:
Joe Wright wrote:
How about '0' bytes instead of '\0' bytes?

What earthly difference could that make?
[Ans: none.]


Presumably the difference is that padding with '0' bytes won't work.
According to the OP, the AES_decrypt requires the last block to be
padded with '\0' bytes.

Silly me. I read Joe's suggestion as "0 bytes instead of '\0' bytes,"
which of course would make no difference. This sort of reading failure
is why debugging is sometimes difficult. My response was obviously
wrong: the difference that Joe's suggestion makes is that it guarantees
failure.
 
J

Joe Wright

Keith said:
Martin Ambuhl said:
Joe said:
(e-mail address removed) wrote:
Again, my problem is NOT the AES_decrypt(). My problem is padding the
input with trailing \0 bytes.


How about '0' bytes instead of '\0' bytes?

What earthly difference could that make?
[Ans: none.]


Presumably the difference is that padding with '0' bytes won't work.
According to the OP, the AES_decrypt requires the last block to be
padded with '\0' bytes.

Joe, what did you have in mind?
The problem seems to be that OP needs 16-byte strings. Clearly an
arbitrarily placed '\0' may shorten the string. Padding with '0'
characters will solve length problem.

The OP may be mis-reading the requirement. Demanding 16-byte strings and
padding with '\0' doesn't make sense.
 
K

Keith Thompson

Joe Wright said:
Keith said:
Martin Ambuhl said:
Joe Wright wrote:

(e-mail address removed) wrote:

Again, my problem is NOT the AES_decrypt(). My problem is padding the
input with trailing \0 bytes.


How about '0' bytes instead of '\0' bytes?

What earthly difference could that make?
[Ans: none.]
Presumably the difference is that padding with '0' bytes won't work.
According to the OP, the AES_decrypt requires the last block to be
padded with '\0' bytes.
Joe, what did you have in mind?
The problem seems to be that OP needs 16-byte strings. Clearly an
arbitrarily placed '\0' may shorten the string. Padding with '0'
characters will solve length problem.

The OP may be mis-reading the requirement. Demanding 16-byte strings
and padding with '\0' doesn't make sense.

I strongly suspect that AES_decrypt() requires 16-byte character
arrays, not strings (at least not the way C defines the term
"string"). Padding a character array with '\0' does make sense; in
fact, this may be one of the few good uses for strncpy().
 
O

Old Wolf

Keith said:
I strongly suspect that AES_decrypt() requires 16-byte character
arrays, not strings (at least not the way C defines the term
"string"). Padding a character array with '\0' does make sense; in
fact, this may be one of the few good uses for strncpy().

Unlikely, as strncpy() will stop reading the source when it
encounters the first '\0' character. I gather from the thread
that the source may contain multiple '\0' characters at
various points.
 
J

Joe Wright

Keith said:
Joe Wright said:
Keith said:
Joe Wright wrote:


(e-mail address removed) wrote:

Again, my problem is NOT the AES_decrypt(). My problem is padding the
input with trailing \0 bytes.


How about '0' bytes instead of '\0' bytes?

What earthly difference could that make?
[Ans: none.]

Presumably the difference is that padding with '0' bytes won't work.
According to the OP, the AES_decrypt requires the last block to be
padded with '\0' bytes.
Joe, what did you have in mind?

The problem seems to be that OP needs 16-byte strings. Clearly an
arbitrarily placed '\0' may shorten the string. Padding with '0'
characters will solve length problem.

The OP may be mis-reading the requirement. Demanding 16-byte strings
and padding with '\0' doesn't make sense.


I strongly suspect that AES_decrypt() requires 16-byte character
arrays, not strings (at least not the way C defines the term
"string"). Padding a character array with '\0' does make sense; in
fact, this may be one of the few good uses for strncpy().

Go for it. Your suspicion is every bit as good as mine. I have no idea
of AES_decrypt() and what it requires. I hope I haven't reduced the S/N
too much.
 
K

Keith Thompson

Old Wolf said:
Unlikely, as strncpy() will stop reading the source when it
encounters the first '\0' character. I gather from the thread
that the source may contain multiple '\0' characters at
various points.

Good point.
 
M

Michael Wojcik

Unfortunately, the problem is that OP needs to be operating on
contiguous sequences of 128 bits, and not strings at all (as defined
by C).

Yes, but not in the way that your suggestion corrects, unfortunately.
I strongly suspect that AES_decrypt() requires 16-byte character
arrays, not strings (at least not the way C defines the term
"string").

More precisely, it requires 128 bits of ciphertext, and not strings
at all.
Padding a character array with '\0' does make sense; in
fact, this may be one of the few good uses for strncpy().

I think strncpy's the wrong approach here. Even where CHAR_BIT is 8,
using strncpy implies that the function operates on strings, which is
not true.

The OP should be passing AES_decrypt a buffer of 128 bits of
ciphertext. If fewer than 128 bits of ciphertext remain, the buffer
should be padded at the end with zero bits. memset and memcpy are
the appropriate functions to use here; if it's necessary to support
platforms where CHAR_BIT is not 8, the code will need to use bit
operations as well, since AES is an octet-granular encoding.
 

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

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top