RICPLT-2981 SubFail go asn into use
[ric-plt/submgr.git] / 3rdparty / libe2ap / BIT_STRING.c
1 /*-
2  * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3  * Redistribution and modifications are permitted subject to BSD license.
4  */
5 #include <asn_internal.h>
6 #include <BIT_STRING.h>
7 #include <asn_internal.h>
8
9 /*
10  * BIT STRING basic type description.
11  */
12 static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
13         (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
14 };
15 asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs = {
16         sizeof(BIT_STRING_t),
17         offsetof(BIT_STRING_t, _asn_ctx),
18         ASN_OSUBV_BIT
19 };
20 asn_TYPE_operation_t asn_OP_BIT_STRING = {
21         OCTET_STRING_free,         /* Implemented in terms of OCTET STRING */
22         BIT_STRING_print,
23         BIT_STRING_compare,
24         OCTET_STRING_decode_ber,   /* Implemented in terms of OCTET STRING */
25         OCTET_STRING_encode_der,   /* Implemented in terms of OCTET STRING */
26         OCTET_STRING_decode_xer_binary,
27         BIT_STRING_encode_xer,
28 #ifdef  ASN_DISABLE_OER_SUPPORT
29         0,
30         0,
31 #else
32         BIT_STRING_decode_oer,
33         BIT_STRING_encode_oer,
34 #endif  /* ASN_DISABLE_OER_SUPPORT */
35 #ifdef  ASN_DISABLE_PER_SUPPORT
36         0,
37         0,
38         0,
39         0,
40 #else
41         BIT_STRING_decode_uper, /* Unaligned PER decoder */
42         BIT_STRING_encode_uper, /* Unaligned PER encoder */
43         OCTET_STRING_decode_aper,       /* Aligned PER decoder */
44         OCTET_STRING_encode_aper,       /* Aligned PER encoder */
45 #endif  /* ASN_DISABLE_PER_SUPPORT */
46         BIT_STRING_random_fill,
47         0       /* Use generic outmost tag fetcher */
48 };
49 asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
50         "BIT STRING",
51         "BIT_STRING",
52         &asn_OP_BIT_STRING,
53         asn_DEF_BIT_STRING_tags,
54         sizeof(asn_DEF_BIT_STRING_tags)
55           / sizeof(asn_DEF_BIT_STRING_tags[0]),
56         asn_DEF_BIT_STRING_tags,        /* Same as above */
57         sizeof(asn_DEF_BIT_STRING_tags)
58           / sizeof(asn_DEF_BIT_STRING_tags[0]),
59         { 0, 0, BIT_STRING_constraint },
60         0, 0,   /* No members */
61         &asn_SPC_BIT_STRING_specs
62 };
63
64 /*
65  * BIT STRING generic constraint.
66  */
67 int
68 BIT_STRING_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
69                       asn_app_constraint_failed_f *ctfailcb, void *app_key) {
70     const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
71
72         if(st && st->buf) {
73                 if((st->size == 0 && st->bits_unused)
74                 || st->bits_unused < 0 || st->bits_unused > 7) {
75                         ASN__CTFAIL(app_key, td, sptr,
76                                 "%s: invalid padding byte (%s:%d)",
77                                 td->name, __FILE__, __LINE__);
78                         return -1;
79                 }
80         } else {
81                 ASN__CTFAIL(app_key, td, sptr,
82                         "%s: value not given (%s:%d)",
83                         td->name, __FILE__, __LINE__);
84                 return -1;
85         }
86
87         return 0;
88 }
89
90 static const char *_bit_pattern[16] = {
91         "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
92         "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
93 };
94
95 asn_enc_rval_t
96 BIT_STRING_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
97                       int ilevel, enum xer_encoder_flags_e flags,
98                       asn_app_consume_bytes_f *cb, void *app_key) {
99         asn_enc_rval_t er = {0, 0, 0};
100         char scratch[128];
101         char *p = scratch;
102         char *scend = scratch + (sizeof(scratch) - 10);
103         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
104         int xcan = (flags & XER_F_CANONICAL);
105         uint8_t *buf;
106         uint8_t *end;
107
108         if(!st || !st->buf)
109                 ASN__ENCODE_FAILED;
110
111         er.encoded = 0;
112
113         buf = st->buf;
114         end = buf + st->size - 1;       /* Last byte is special */
115
116         /*
117          * Binary dump
118          */
119         for(; buf < end; buf++) {
120                 int v = *buf;
121                 int nline = xcan?0:(((buf - st->buf) % 8) == 0);
122                 if(p >= scend || nline) {
123                         ASN__CALLBACK(scratch, p - scratch);
124                         p = scratch;
125                         if(nline) ASN__TEXT_INDENT(1, ilevel);
126                 }
127                 memcpy(p + 0, _bit_pattern[v >> 4], 4);
128                 memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
129                 p += 8;
130         }
131
132         if(!xcan && ((buf - st->buf) % 8) == 0)
133                 ASN__TEXT_INDENT(1, ilevel);
134         ASN__CALLBACK(scratch, p - scratch);
135         p = scratch;
136
137         if(buf == end) {
138                 int v = *buf;
139                 int ubits = st->bits_unused;
140                 int i;
141                 for(i = 7; i >= ubits; i--)
142                         *p++ = (v & (1 << i)) ? 0x31 : 0x30;
143                 ASN__CALLBACK(scratch, p - scratch);
144         }
145
146         if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
147
148         ASN__ENCODED_OK(er);
149 cb_failed:
150         ASN__ENCODE_FAILED;
151 }
152
153
154 /*
155  * BIT STRING specific contents printer.
156  */
157 int
158 BIT_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
159                  asn_app_consume_bytes_f *cb, void *app_key) {
160     const char * const h2c = "0123456789ABCDEF";
161         char scratch[64];
162         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
163         uint8_t *buf;
164         uint8_t *end;
165         char *p = scratch;
166
167         (void)td;       /* Unused argument */
168
169         if(!st || !st->buf)
170                 return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
171
172         ilevel++;
173         buf = st->buf;
174         end = buf + st->size;
175
176         /*
177          * Hexadecimal dump.
178          */
179         for(; buf < end; buf++) {
180                 if((buf - st->buf) % 16 == 0 && (st->size > 16)
181                                 && buf != st->buf) {
182                         _i_INDENT(1);
183                         /* Dump the string */
184                         if(cb(scratch, p - scratch, app_key) < 0) return -1;
185                         p = scratch;
186                 }
187                 *p++ = h2c[*buf >> 4];
188                 *p++ = h2c[*buf & 0x0F];
189                 *p++ = 0x20;
190         }
191
192         if(p > scratch) {
193                 p--;    /* Eat the tailing space */
194
195                 if((st->size > 16)) {
196                         _i_INDENT(1);
197                 }
198
199                 /* Dump the incomplete 16-bytes row */
200                 if(cb(scratch, p - scratch, app_key) < 0)
201                         return -1;
202         }
203
204     if(st->bits_unused) {
205         int ret = snprintf(scratch, sizeof(scratch), " (%d bit%s unused)",
206                            st->bits_unused, st->bits_unused == 1 ? "" : "s");
207         assert(ret > 0 && ret < (ssize_t)sizeof(scratch));
208         if(ret > 0 && ret < (ssize_t)sizeof(scratch)
209            && cb(scratch, ret, app_key) < 0)
210             return -1;
211     }
212
213         return 0;
214 }
215
216 /*
217  * Non-destructively remove the trailing 0-bits from the given bit string.
218  */
219 static const BIT_STRING_t *
220 BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp) {
221     const uint8_t *b;
222     union {
223         const uint8_t *c_buf;
224         uint8_t *nc_buf;
225     } unconst;
226
227     if(st->size == 0) {
228         assert(st->bits_unused == 0);
229         return st;
230     } else {
231         for(b = &st->buf[st->size - 1]; b > st->buf && *b == 0; b--) {
232             ;
233         }
234         /* b points to the last byte which may contain data */
235         if(*b) {
236             int unused = 7;
237             uint8_t v = *b;
238             v &= -(int8_t)v;
239             if(v & 0x0F) unused -= 4;
240             if(v & 0x33) unused -= 2;
241             if(v & 0x55) unused -= 1;
242             tmp->size = b-st->buf + 1;
243             tmp->bits_unused = unused;
244         } else {
245             tmp->size = b-st->buf;
246             tmp->bits_unused = 0;
247         }
248
249         assert(b >= st->buf);
250     }
251
252     unconst.c_buf = st->buf;
253     tmp->buf = unconst.nc_buf;
254     return tmp;
255 }
256
257 /*
258  * Lexicographically compare the common prefix of both strings,
259  * and if it is the same return -1 for the smallest string.
260  */
261 int
262 BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
263                    const void *bptr) {
264     /*
265      * Remove information about trailing bits, since
266      * X.680 (08/2015) #22.7 "ensure that different semantics are not"
267      * "associated with [values that differ only in] the trailing 0 bits."
268      */
269     BIT_STRING_t compact_a, compact_b;
270     const BIT_STRING_t *a = BIT_STRING__compactify(aptr, &compact_a);
271     const BIT_STRING_t *b = BIT_STRING__compactify(bptr, &compact_b);
272     const asn_OCTET_STRING_specifics_t *specs = td->specifics;
273
274     assert(specs && specs->subvariant == ASN_OSUBV_BIT);
275
276     if(a && b) {
277         size_t common_prefix_size = a->size <= b->size ? a->size : b->size;
278         int ret = memcmp(a->buf, b->buf, common_prefix_size);
279         if(ret == 0) {
280             /* Figure out which string with equal prefixes is longer. */
281             if(a->size < b->size) {
282                 return -1;
283             } else if(a->size > b->size) {
284                 return 1;
285             } else {
286                 /* Figure out how many unused bits */
287                 if(a->bits_unused > b->bits_unused) {
288                     return -1;
289                 } else if(a->bits_unused < b->bits_unused) {
290                     return 1;
291                 } else {
292                     return 0;
293                 }
294             }
295         } else {
296             return ret;
297         }
298     } else if(!a && !b) {
299         return 0;
300     } else if(!a) {
301         return -1;
302     } else {
303         return 1;
304     }
305 }
306
307 #ifndef  ASN_DISABLE_PER_SUPPORT
308
309 #undef  RETURN
310 #define RETURN(_code)                       \
311     do {                                    \
312         asn_dec_rval_t tmprval;             \
313         tmprval.code = _code;               \
314         tmprval.consumed = consumed_myself; \
315         return tmprval;                     \
316     } while(0)
317
318 static asn_per_constraint_t asn_DEF_BIT_STRING_constraint_size = {
319     APC_SEMI_CONSTRAINED, -1, -1, 0, 0};
320
321 asn_dec_rval_t
322 BIT_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
323                        const asn_TYPE_descriptor_t *td,
324                        const asn_per_constraints_t *constraints, void **sptr,
325                        asn_per_data_t *pd) {
326     const asn_OCTET_STRING_specifics_t *specs = td->specifics
327                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
328                 : &asn_SPC_BIT_STRING_specs;
329     const asn_per_constraints_t *pc =
330         constraints ? constraints : td->encoding_constraints.per_constraints;
331         const asn_per_constraint_t *csiz;
332         asn_dec_rval_t rval = { RC_OK, 0 };
333         BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
334         ssize_t consumed_myself = 0;
335         int repeat;
336
337         (void)opt_codec_ctx;
338
339         if(pc) {
340                 csiz = &pc->size;
341         } else {
342                 csiz = &asn_DEF_BIT_STRING_constraint_size;
343         }
344
345         if(specs->subvariant != ASN_OSUBV_BIT) {
346                 ASN_DEBUG("Subvariant %d is not BIT OSUBV_BIT", specs->subvariant);
347                 RETURN(RC_FAIL);
348     }
349
350         /*
351          * Allocate the string.
352          */
353         if(!st) {
354                 st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
355                 if(!st) RETURN(RC_FAIL);
356         }
357
358         ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
359                 csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
360                 csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
361
362         if(csiz->flags & APC_EXTENSIBLE) {
363                 int inext = per_get_few_bits(pd, 1);
364                 if(inext < 0) RETURN(RC_WMORE);
365                 if(inext) {
366                         csiz = &asn_DEF_BIT_STRING_constraint_size;
367                 }
368         }
369
370         if(csiz->effective_bits >= 0) {
371                 FREEMEM(st->buf);
372         st->size = (csiz->upper_bound + 7) >> 3;
373         st->buf = (uint8_t *)MALLOC(st->size + 1);
374                 if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
375         }
376
377         /* X.691, #16.5: zero-length encoding */
378         /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
379         /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
380         if(csiz->effective_bits == 0) {
381                 int ret;
382         ASN_DEBUG("Encoding BIT STRING size %ld", csiz->upper_bound);
383         ret = per_get_many_bits(pd, st->buf, 0, csiz->upper_bound);
384                 if(ret < 0) RETURN(RC_WMORE);
385                 consumed_myself += csiz->upper_bound;
386                 st->buf[st->size] = 0;
387         st->bits_unused = (8 - (csiz->upper_bound & 0x7)) & 0x7;
388         RETURN(RC_OK);
389         }
390
391         st->size = 0;
392         do {
393                 ssize_t raw_len;
394                 ssize_t len_bytes;
395                 ssize_t len_bits;
396                 void *p;
397                 int ret;
398
399                 /* Get the PER length */
400                 raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound,
401                                           &repeat);
402                 if(raw_len < 0) RETURN(RC_WMORE);
403         if(raw_len == 0 && st->buf) break;
404
405                 ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
406                         (long)csiz->effective_bits, (long)raw_len,
407                         repeat ? "repeat" : "once", td->name);
408         len_bits = raw_len;
409         len_bytes = (len_bits + 7) >> 3;
410         if(len_bits & 0x7) st->bits_unused = 8 - (len_bits & 0x7);
411         /* len_bits be multiple of 16K if repeat is set */
412         p = REALLOC(st->buf, st->size + len_bytes + 1);
413                 if(!p) RETURN(RC_FAIL);
414                 st->buf = (uint8_t *)p;
415
416         ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
417         if(ret < 0) RETURN(RC_WMORE);
418                 st->size += len_bytes;
419         } while(repeat);
420         st->buf[st->size] = 0;  /* nul-terminate */
421
422         return rval;
423 }
424
425 asn_enc_rval_t
426 BIT_STRING_encode_uper(const asn_TYPE_descriptor_t *td,
427                        const asn_per_constraints_t *constraints,
428                        const void *sptr, asn_per_outp_t *po) {
429     const asn_OCTET_STRING_specifics_t *specs =
430         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
431                       : &asn_SPC_BIT_STRING_specs;
432     const asn_per_constraints_t *pc =
433         constraints ? constraints : td->encoding_constraints.per_constraints;
434         const asn_per_constraint_t *csiz;
435         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
436         BIT_STRING_t compact_bstr;  /* Do not modify this directly! */
437         asn_enc_rval_t er = { 0, 0, 0 };
438         int inext = 0;          /* Lies not within extension root */
439         size_t size_in_bits;
440         const uint8_t *buf;
441         int ret;
442         int ct_extensible;
443
444         if(!st || (!st->buf && st->size))
445                 ASN__ENCODE_FAILED;
446
447         if(specs->subvariant == ASN_OSUBV_BIT) {
448         if((st->size == 0 && st->bits_unused) || (st->bits_unused & ~7))
449             ASN__ENCODE_FAILED;
450     } else {
451                 ASN__ENCODE_FAILED;
452     }
453
454         if(pc) {
455         csiz = &pc->size;
456     } else {
457                 csiz = &asn_DEF_BIT_STRING_constraint_size;
458         }
459         ct_extensible = csiz->flags & APC_EXTENSIBLE;
460
461     /* Figure out the size without the trailing bits */
462     st = BIT_STRING__compactify(st, &compact_bstr);
463     size_in_bits = 8 * st->size - st->bits_unused;
464
465     ASN_DEBUG(
466         "Encoding %s into %" ASN_PRI_SIZE " bits"
467         " (%ld..%ld, effective %d)%s",
468         td->name, size_in_bits, csiz->lower_bound, csiz->upper_bound,
469         csiz->effective_bits, ct_extensible ? " EXT" : "");
470
471     /* Figure out whether size lies within PER visible constraint */
472
473     if(csiz->effective_bits >= 0) {
474         if((ssize_t)size_in_bits > csiz->upper_bound) {
475             if(ct_extensible) {
476                 csiz = &asn_DEF_BIT_STRING_constraint_size;
477                 inext = 1;
478             } else {
479                 ASN__ENCODE_FAILED;
480             }
481         }
482     } else {
483         inext = 0;
484     }
485
486     if(ct_extensible) {
487                 /* Declare whether length is [not] within extension root */
488                 if(per_put_few_bits(po, inext, 1))
489                         ASN__ENCODE_FAILED;
490         }
491
492     if(csiz->effective_bits >= 0 && !inext) {
493         int add_trailer = (ssize_t)size_in_bits < csiz->lower_bound;
494         ASN_DEBUG(
495             "Encoding %" ASN_PRI_SIZE " bytes (%ld), length (in %d bits) trailer %d; actual "
496             "value %" ASN_PRI_SSIZE "",
497             st->size, size_in_bits - csiz->lower_bound, csiz->effective_bits,
498             add_trailer,
499             add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound);
500         ret = per_put_few_bits(
501             po, add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound,
502             csiz->effective_bits);
503         if(ret) ASN__ENCODE_FAILED;
504         ret = per_put_many_bits(po, st->buf, size_in_bits);
505         if(ret) ASN__ENCODE_FAILED;
506         if(add_trailer) {
507             static const uint8_t zeros[16];
508             size_t trailing_zero_bits = csiz->lower_bound - size_in_bits;
509             while(trailing_zero_bits > 0) {
510                 if(trailing_zero_bits > 8 * sizeof(zeros)) {
511                     ret = per_put_many_bits(po, zeros, 8 * sizeof(zeros));
512                     trailing_zero_bits -= 8 * sizeof(zeros);
513                 } else {
514                     ret = per_put_many_bits(po, zeros, trailing_zero_bits);
515                     trailing_zero_bits = 0;
516                 }
517                 if(ret) ASN__ENCODE_FAILED;
518             }
519         }
520         ASN__ENCODED_OK(er);
521     }
522
523     ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size);
524
525     buf = st->buf;
526     do {
527         int need_eom = 0;
528         ssize_t maySave = uper_put_length(po, size_in_bits, &need_eom);
529         if(maySave < 0) ASN__ENCODE_FAILED;
530
531         ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "", maySave, size_in_bits);
532
533         ret = per_put_many_bits(po, buf, maySave);
534         if(ret) ASN__ENCODE_FAILED;
535
536         buf += maySave >> 3;
537         size_in_bits -= maySave;
538         assert(!(maySave & 0x07) || !size_in_bits);
539         if(need_eom && uper_put_length(po, 0, 0))
540             ASN__ENCODE_FAILED; /* End of Message length */
541     } while(size_in_bits);
542
543     ASN__ENCODED_OK(er);
544 }
545
546 #endif  /* ASN_DISABLE_PER_SUPPORT */
547
548 asn_random_fill_result_t
549 BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
550                        const asn_encoding_constraints_t *constraints,
551                        size_t max_length) {
552     const asn_OCTET_STRING_specifics_t *specs =
553         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
554                       : &asn_SPC_BIT_STRING_specs;
555     asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
556     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
557     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
558     static unsigned lengths[] = {0,     1,     2,     3,     4,     8,
559                                  126,   127,   128,   16383, 16384, 16385,
560                                  65534, 65535, 65536, 65537};
561     uint8_t *buf;
562     uint8_t *bend;
563     uint8_t *b;
564     size_t rnd_bits, rnd_len;
565     BIT_STRING_t *st;
566
567     if(max_length == 0) return result_skipped;
568
569     switch(specs->subvariant) {
570     case ASN_OSUBV_ANY:
571         return result_failed;
572     case ASN_OSUBV_BIT:
573         break;
574     default:
575         break;
576     }
577
578     /* Figure out how far we should go */
579     rnd_bits = lengths[asn_random_between(
580         0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
581     if(!constraints || !constraints->per_constraints)
582         constraints = &td->encoding_constraints;
583     if(constraints->per_constraints) {
584         const asn_per_constraint_t *pc = &constraints->per_constraints->size;
585         if(pc->flags & APC_CONSTRAINED) {
586             long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
587                                              ? pc->upper_bound
588                                              : (ssize_t)max_length;
589             if(max_length < (size_t)pc->lower_bound) {
590                 return result_skipped;
591             }
592             if(pc->flags & APC_EXTENSIBLE) {
593                 switch(asn_random_between(0, 5)) {
594                 case 0:
595                     if(pc->lower_bound > 0) {
596                         rnd_bits = pc->lower_bound - 1;
597                         break;
598                     }
599                     /* Fall through */
600                 case 1:
601                     rnd_bits = pc->upper_bound + 1;
602                     break;
603                 case 2:
604                     /* Keep rnd_bits from the table */
605                     if(rnd_bits < max_length) {
606                         break;
607                     }
608                     /* Fall through */
609                 default:
610                     rnd_bits = asn_random_between(pc->lower_bound,
611                                                   suggested_upper_bound);
612                 }
613             } else {
614                 rnd_bits =
615                     asn_random_between(pc->lower_bound, suggested_upper_bound);
616             }
617         } else {
618             rnd_bits = asn_random_between(0, max_length - 1);
619         }
620     } else if(rnd_bits >= max_length) {
621         rnd_bits = asn_random_between(0, max_length - 1);
622     }
623
624     rnd_len = (rnd_bits + 7) / 8;
625     buf = CALLOC(1, rnd_len + 1);
626     if(!buf) return result_failed;
627
628     bend = &buf[rnd_len];
629
630     for(b = buf; b < bend; b++) {
631         *(uint8_t *)b = asn_random_between(0, 255);
632     }
633     *b = 0; /* Zero-terminate just in case. */
634
635     if(*sptr) {
636         st = *sptr;
637         FREEMEM(st->buf);
638     } else {
639         st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
640         if(!st) {
641             FREEMEM(buf);
642             return result_failed;
643         }
644     }
645
646     st->buf = buf;
647     st->size = rnd_len;
648     st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7;
649     if(st->bits_unused) {
650         assert(st->size > 0);
651         st->buf[st->size-1] &= 0xff << st->bits_unused;
652     }
653
654     result_ok.length = st->size;
655     return result_ok;
656 }