/*************************************************************************
* Copyright (C) 2005 Intel Corporation
*
* Licensed under the Apache License,  Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 	http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law  or agreed  to  in  writing,  software
* distributed under  the License  is  distributed  on  an  "AS IS"  BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the  specific  language  governing  permissions  and
* limitations under the License.
*************************************************************************/

/* 
// 
//  Purpose:
//     Cryptography Primitive.
//     DL over Prime Finite Field (setup/retrieve domain parameters)
// 
//  Contents:
//        ippsDLPSetDP()
//
*/

#include "owndefs.h"
#include "owncp.h"
#include "pcpdlp.h"

/*F*
//    Name: ippsDLPSetDP
//
// Purpose: Set tagged DL Domain Parameter.
//
// Returns:                Reason:
//    ippStsNullPtrErr        NULL == pDP
//                            NULL == pDL
//
//    ippStsContextMatchErr   illegal pDP->idCtx
//                            illegal pDL->idCtx
//
//    ippStsRangeErr          not enough room for pDP
//
//    ippStsBadArgErr         invalid key tag
//
//    errors produced by      ippsMontSet()
//                            ippsMontForm()
//
//    ippStsNoErr             no errors
//
// Parameters:
//    pDP      pointer to the DL domain parameter
//    tag      DLP key component tag
//    pDL      pointer to the DL context
//
*F*/
IPPFUN(IppStatus, ippsDLPSetDP,(const IppsBigNumState* pDP, IppDLPKeyTag tag, IppsDLPState* pDL))
{
   /* test DL context */
   IPP_BAD_PTR1_RET(pDL);
   IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr);

   /* test DL parameter to be set */
   IPP_BAD_PTR1_RET(pDP);
   IPP_BADARG_RET(!BN_VALID_ID(pDP), ippStsContextMatchErr);
   IPP_BADARG_RET(BN_NEGATIVE(pDP), ippStsBadArgErr);

   {
      IppStatus sts = ippStsNoErr;

      cpBN_zero(DLP_X(pDL));
      cpBN_zero(DLP_YENC(pDL));

      switch(tag) {
         case ippDLPkeyP:
            DLP_FLAG(pDL) &=(Ipp32u)~ippDLPkeyP;
            sts = gsModEngineInit(DLP_MONTP0(pDL), (Ipp32u*)BN_NUMBER(pDP), cpBN_bitsize(pDP), DLP_MONT_POOL_LENGTH, gsModArithDLP());
            if(ippStsNoErr==sts) {
               DLP_FLAG(pDL) |= ippDLPkeyP;
            }
            break;
         case ippDLPkeyR:
            DLP_FLAG(pDL) &=(Ipp32u)~ippDLPkeyR;
            sts = gsModEngineInit(DLP_MONTR(pDL), (Ipp32u*)BN_NUMBER(pDP), cpBN_bitsize(pDP), DLP_MONT_POOL_LENGTH, gsModArithDLP());
            if(ippStsNoErr==sts)
               DLP_FLAG(pDL) |= ippDLPkeyR;
            break;
         case ippDLPkeyG:
            DLP_FLAG(pDL) &=(Ipp32u)~ippDLPkeyG;
            if(DLP_FLAG(pDL)&ippDLPkeyP) {
               cpMontEnc_BN(DLP_GENC(pDL), pDP, DLP_MONTP0(pDL));
               DLP_FLAG(pDL) |= ippDLPkeyG;
            }
            else
               sts = ippStsIncompleteContextErr;
            break;
         default:
            sts = ippStsBadArgErr;
      }

      return sts;
   }
}
