Encoding TS24301Msg_PDU

The procedure for encoding TS24301Msg_PDU is basically the same as given above. When the message is to be encoded with security protection, however, there are a few additional requirements. These steps are not necessary when encoding a message without security protection.

For security protected messages, including SERVICE REQUEST messages (which always have integrity protection):

  1. Initialize the NAS security context

  2. Specify the algorithm and keys to use

  3. Set NAS security parameters

  4. Assign security header fields in the PDU.

  5. Free the NAS security context when finished.

The following code illustrates these steps. It encodes an ACTIVATE DEDICATED EPS BEARER CONTEXT ACCEPT message with both integrity and confidentiality protection.

#include "TS24301Msgs.h"
#include "rt3gppsrc/rt3gppNasSec.h"

int main (int argc, char** argv)
    TS24301Msg_PDU pdu;
    TS24301Msg_ActvDedEPSBearerCtxtAcc data;
    TS24301Msg_ActvDedEPSBearerCtxtAcc* pvalue = &data;
    OSCTXT	ctxt;
    OSOCTET	msgbuf[256], *msgptr;
    OSSIZE       len;
    int		i, ret;
    OSCrypt128Key integKey = { ... };
    OSCrypt128Key encryptKey = { ... };
    /* Initialize context structure */
    ret = rtInitContext (&ctxt);
    if (0 != ret) {
        printf ("rtInitContext failed; status = %d\n", ret);
        rtxErrPrint (&ctxt);
        return ret;
    /* Initialize the NAS Security context */   
    ret = rtx3gppSecInitialize(&ctxt);
    if (0 != ret) {
        rtxErrPrint (&ctxt);
    /* Specify the integrity and encryption algorithms and keys.
    This only needs to be done the first time or when these values change
    ret = rtx3gppAssignAlgorithmKeys(&ctxt, &integKey, &encryptKey,
    OS3GPPSecAlgorithm_AES, OS3GPPSecAlgorithm_AES);
    if (0 != ret) {
        rtxErrPrint (&ctxt);
    /* Assign count, bearerId, direction in the NAS security context.
    These act as input into the security algorithms.
    ctxt.p3gppSec->count = 15;
    ctxt.p3gppSec->bearerId = 0;
    ctxt.p3gppSec->direction = 0; /*uplink*/   
    /* Populate data structure */
    asn1Init_TS24301Msg_PDU (&pdu);
    /* Specify the security header is present. Populate the security header
    fields. The security header's protocol discriminator is always EPS
    Mobility management. The msgAuthCode field will be filled in by function
    pdu.m.secHdrPresent = 1;
    pdu.secHdr.secHdrType = TS24007L3_SecHdrType_integProtAndCipher;
    pdu.secHdr.protoDiscr = TS24007L3_ProtoDiscr_epsMobMgmt;
    pdu.secHdr.seqNumber  = 1;
    /* The skipIndicator is used for the message's ESP bearer identity;
    it is always zero. The PDU's protocol discriminator (unlike the security
    header's protocol discriminator above) is set according to the message
    being protected.
    pdu.l3HdrOpts.t = T_TS24007L3_L3HdrOptions_skipInd;
    pdu.l3HdrOpts.u.skipInd = 0;
    pdu.protoDiscr = TS24007L3_ProtoDiscr_epsSessMgmt;
    pdu.msgType = ASN1V_ts24301Msg_mt_ActvDedEPSBearerCtxtAcc;
    /* Encode data.
    NASEnc_TS24301Msg_PDU will encrypt the message and compute the message
    authentication code according to the security settings chosen above.
    rtxCtxtSetBufPtr (&ctxt, msgbuf, sizeof(msgbuf));
    ret = NASEnc_TS24301Msg_PDU (&ctxt, &pdu);
    if (0 != ret) {
        printf ("encode PDU failed; status = %d\n", ret);
        rtxErrPrint (&ctxt);
        return ret;
    /* Free the NAS security context */

When the message being security protected is a SERVICE REQUEST message, the above procedure is basically the same, but a few differences do exist: