FreeRTOS-Plus/ThirdParty/WolfSSL-FIPS-Ready/wolfcrypt/src/asn.c
/* build DER formatted ECC key, include optional public key if requested,
 * return length on success, negative on error */
build DER formatted ECC key, include optional public key if requested,
return length on success, negative on error
build DER formatted ECC key include optional public key if requested return length on success negative on error
static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
                             int pubIn)
{
    byte   curve[MAX_ALGO_SZ+2];
    byte   ver[MAX_VERSION_SZ];
    byte   seq[MAX_SEQ_SZ];
    byte   *prv = NULL, *pub = NULL;
    int    ret, totalSz, curveSz, verSz;
    int    privHdrSz  = ASN_ECC_HEADER_SZ;
    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
    if (key == NULL || output == NULL || inLen == 0)
        return BAD_FUNC_ARG;
    curve[curveidx++] = ECC_PREFIX_0;
    curveidx++ ;
    curveSz = SetCurve(key, curve+curveidx);
    if (curveSz < 0)
        return curveSz;
    curve[1] = (byte)curveSz;
    curveidx += curveSz;
    privSz = key->dp->size;
    prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
                         key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    if (prv == NULL) {
        return MEMORY_E;
    }
    prvidx += SetOctetString8Bit(key->dp->size, &prv[prvidx]);
    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
    if (ret < 0) {
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
        return ret;
    }
    prvidx += privSz;
    if (pubIn) {
        ret = wc_ecc_export_x963(key, NULL, &pubSz);
        if (ret != LENGTH_ONLY_E) {
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
            return ret;
        }
        pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
                             key->heap, DYNAMIC_TYPE_TMP_BUFFER);
        if (pub == NULL) {
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
            return MEMORY_E;
        }
        pub[pubidx++] = ECC_PREFIX_1;
        if (pubSz > 128) 
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
        else 
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
        pubidx += SetBitString(pubSz, 0, pub + pubidx);
        ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
        if (ret != 0) {
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
            return ret;
        }
        pubidx += pubSz;
    }
    verSz = SetMyVersion(1, ver, FALSE);
    seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
    totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
    if (totalSz > (int)inLen) {
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
        if (pubIn) {
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
        }
        return BAD_FUNC_ARG;
    }
    XMEMCPY(output + idx, seq, seqSz);
    idx = seqSz;
    XMEMCPY(output + idx, ver, verSz);
    idx += verSz;
    XMEMCPY(output + idx, prv, prvidx);
    idx += prvidx;
    XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    XMEMCPY(output + idx, curve, curveidx);
    idx += curveidx;
    if (pubIn) {
        XMEMCPY(output + idx, pub, pubidx);
        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    }
    return totalSz;
}
static int wc_BuildEccKeyDer ( ecc_key * key , byte * output , word32 inLen , int pubIn ) { byte curve [ MAX_ALGO_SZ + 2 ] ; byte ver [ MAX_VERSION_SZ ] ; byte seq [ MAX_SEQ_SZ ] ; byte * prv = NULL , * pub = NULL ; int ret , totalSz , curveSz , verSz ; int privHdrSz = ASN_ECC_HEADER_SZ ; int pubHdrSz = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ ; word32 idx = 0 , prvidx = 0 , pubidx = 0 , curveidx = 0 ; word32 seqSz , privSz , pubSz = ECC_BUFSIZE ; if ( key == NULL || output == NULL || inLen == 0 ) return BAD_FUNC_ARG ; curve [ curveidx ++ ] = ECC_PREFIX_0 ; curveidx ++ ; curveSz = SetCurve ( key , curve + curveidx ) ; if ( curveSz < 0 ) return curveSz ; curve [ 1 ] = ( byte ) curveSz ; curveidx += curveSz ; privSz = key -> dp -> size ; prv = ( byte * ) XMALLOC ( privSz + privHdrSz + MAX_SEQ_SZ , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; if ( prv == NULL ) { return MEMORY_E ; } prvidx += SetOctetString8Bit ( key -> dp -> size , & prv [ prvidx ] ) ; ret = wc_ecc_export_private_only ( key , prv + prvidx , & privSz ) ; if ( ret < 0 ) { XFREE ( prv , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; return ret ; } prvidx += privSz ; if ( pubIn ) { ret = wc_ecc_export_x963 ( key , NULL , & pubSz ) ; if ( ret != LENGTH_ONLY_E ) { XFREE ( prv , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; return ret ; } pub = ( byte * ) XMALLOC ( pubSz + pubHdrSz + MAX_SEQ_SZ , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; if ( pub == NULL ) { XFREE ( prv , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; return MEMORY_E ; } pub [ pubidx ++ ] = ECC_PREFIX_1 ; if ( pubSz > 128 ) pubidx += SetLength ( pubSz + ASN_ECC_CONTEXT_SZ + 2 , pub + pubidx ) ; else pubidx += SetLength ( pubSz + ASN_ECC_CONTEXT_SZ + 1 , pub + pubidx ) ; pubidx += SetBitString ( pubSz , 0 , pub + pubidx ) ; ret = wc_ecc_export_x963 ( key , pub + pubidx , & pubSz ) ; if ( ret != 0 ) { XFREE ( prv , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; XFREE ( pub , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; return ret ; } pubidx += pubSz ; } verSz = SetMyVersion ( 1 , ver , FALSE ) ; seqSz = SetSequence ( verSz + prvidx + pubidx + curveidx , seq ) ; totalSz = prvidx + pubidx + curveidx + verSz + seqSz ; if ( totalSz > ( int ) inLen ) { XFREE ( prv , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; if ( pubIn ) { XFREE ( pub , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; } return BAD_FUNC_ARG ; } XMEMCPY ( output + idx , seq , seqSz ) ; idx = seqSz ; XMEMCPY ( output + idx , ver , verSz ) ; idx += verSz ; XMEMCPY ( output + idx , prv , prvidx ) ; idx += prvidx ; XFREE ( prv , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; XMEMCPY ( output + idx , curve , curveidx ) ; idx += curveidx ; if ( pubIn ) { XMEMCPY ( output + idx , pub , pubidx ) ; XFREE ( pub , key -> heap , DYNAMIC_TYPE_TMP_BUFFER ) ; } return totalSz ; }
build DER formatted ECC key, include optional public key if requested,
 return length on success, negative on error
build DER formatted ECC key include optional public key if requested return length on success negative on error
/* curve */ /* to put the size after computation */ /* set computed size */ /* private */ /* pubIn */ /* leading zero + extra size byte */ /* leading zero */ /* SetBitString adds leading zero */ /* make headers */ /* write out */ /* seq */ /* ver */ /* private */ /* curve */ /* pubIn */ /* idx += pubidx;  not used after write, if more data remove comment */